Thread Tools Display Modes
11/12/14, 01:03 PM   #1
merlight
AddOn Author - Click to view addons
Join Date: Jul 2014
Posts: 671
[outdated] ZO_ComboBox sort order

ZO_ComboBox allows custom ordering of items via ZO_ComboBox:SetSortOrder(sortOrder, sortType)
I can attach custom data to entries, and use them for sorting, but currently only as tiebreakers. The limitation lies in function ComboBoxSortHelper, where "name" is hardcoded as the primary sort key.

I have a combo box with 1 "default" item and a variable number of user-created items. The "default" item shall always be on top of the drop-down list, while the rest should be properly sorted (they can be added/removed at run-time). So I added "priority" key to each entry, the "default" entry has priority=1, user entries have priority=2. Now I want to set "priority" as the primary sort key, and "name" as the tiebreaker, like this:
Lua Code:
  1. combo:SetSortOrder(ZO_SORT_ORDER_UP, {priority={tiebreaker="name"}, name={}})
  2. combo:SetPrimarySortKey("priority") -- or a third parameter to the previous function, doesn't matter much
 
11/12/14, 07:36 PM   #2
circonian
AddOn Author - Click to view addons
Join Date: May 2014
Posts: 613
Originally Posted by merlight View Post
ZO_ComboBox allows custom ordering of items via ZO_ComboBox:SetSortOrder(sortOrder, sortType)
I can attach custom data to entries, and use them for sorting, but currently only as tiebreakers. The limitation lies in function ComboBoxSortHelper, where "name" is hardcoded as the primary sort key.

I have a combo box with 1 "default" item and a variable number of user-created items. The "default" item shall always be on top of the drop-down list, while the rest should be properly sorted (they can be added/removed at run-time). So I added "priority" key to each entry, the "default" entry has priority=1, user entries have priority=2. Now I want to set "priority" as the primary sort key, and "name" as the tiebreaker, like this:
Lua Code:
  1. combo:SetSortOrder(ZO_SORT_ORDER_UP, {priority={tiebreaker="name"}, name={}})
  2. combo:SetPrimarySortKey("priority") -- or a third parameter to the previous function, doesn't matter much
This one may or may not be possible, but if your only populating the box once, you could add everything except the top item, sort it & then insert the top item in key = 1 position:
Lua Code:
  1. table.insert(comboBox.m_sortedItems, 1, {name = "top of the list", control ="whatever", ...})

Or probably a better idea would be to just sort the table yourself...or partial do it yourself. Call table.sort & call your own sort function to check if one of the items is the item you want at the top of the list & return the appropriate value, else pass it on to the ZO_TableOrderingFunction to sort by name.
Lua Code:
  1. local function MySort(item1, item2)
  2.     if item1.name == "top of the list" then
  3.         return true
  4.     elseif item2.name == "top of the list" then
  5.         return false
  6.     end
  7.     return ZO_TableOrderingFunction(item1, item2, "name", comboBox.m_sortType, comboBox.m_sortOrder)
  8. end
  9.    
  10. table.sort(comboBox.m_sortedItems, function(item1, item2) return MySort(item1, item2) end)

Oh, and if your storing other data in there besides name and were wanting to sort by that, you could still do the same thing just alter it for whatever data you wanted to sort by. You could pass whatever key you want to ZO_TableOrderingFunction, or just do the entire sort yourself in your own MySort() function.
You just may also need to manually set (if they need changed):
Lua Code:
  1. comboBox.m_sortOrder = sortOrder or ZO_SORT_ORDER_UP
  2. comboBox.m_sortType = sortType or ZO_SORT_BY_NAME

Last edited by circonian : 11/12/14 at 07:42 PM.
 
11/12/14, 07:41 PM   #3
merlight
AddOn Author - Click to view addons
Join Date: Jul 2014
Posts: 671
Yes it's perfectly doable. I will SetSortsItems(false) and override UpdateItems() using my desired sort method. I placed this in the Wish-List section as it would be nice if the control allowed me to simply set the primary sort key
 
11/12/14, 07:50 PM   #4
circonian
AddOn Author - Click to view addons
Join Date: May 2014
Posts: 613
Originally Posted by merlight View Post
Yes it's perfectly doable. I will SetSortsItems(false) and override UpdateItems() using my desired sort method. I placed this in the Wish-List section as it would be nice if the control allowed me to simply set the primary sort key
Clicked on this from "Todays Posts" didn't even realize it was in the wish section, but yeah it would be nice.
 
11/12/14, 07:53 PM   #5
merlight
AddOn Author - Click to view addons
Join Date: Jul 2014
Posts: 671
Oh and to top if off, I've now discovered a bug. ZO_ComboBox:UpdateItems() begins with this condition:
Lua Code:
  1. if self.m_sortOrder and self.m_sortsItems then
  2.     table.sort(...)
  3. end

But since ZO_SORT_ORDER_DOWN == false, items will not be sorted at all if you specify descending order. The condition should only check m_sortsItems.

Edit: the bug extends to SetSortOrder() as well:
Lua Code:
  1. function ZO_ComboBox:SetSortOrder(sortOrder, sortType)
  2.     self.m_sortOrder = sortOrder or ZO_SORT_ORDER_UP -- wrong
  3.     self.m_sortType = sortType or ZO_SORT_BY_NAME
  4.     self:UpdateItems()                                
  5. end

m_sortOrder will always end up being UP, because DOWN == false.

Last edited by merlight : 11/12/14 at 07:57 PM.
 
11/13/14, 12:37 AM   #6
sirinsidiator
 
sirinsidiator's Avatar
AddOn Author - Click to view addons
Join Date: Apr 2014
Posts: 1,578
You should also take a look at the enchantment filter for the trading house.
They have a similar problem where they want to sort the list except for the first and last element
Code:
	-- Sort the tables, ensuring that the first and last entries of each table remain anchored ('any' and 'other' filters).
	for _, v in pairs(enchantmentTypes) do
		ZO_TradingHouse_SortComboBoxEntries(v, ZO_SORT_BY_NAME, ZO_SORT_ORDER_UP, ANCHOR_FIRST_ENTRY, ANCHOR_LAST_ENTRY)
	end
 
11/13/14, 06:57 AM   #7
merlight
AddOn Author - Click to view addons
Join Date: Jul 2014
Posts: 671
Originally Posted by sirinsidiator View Post
You should also take a look at the enchantment filter for the trading house.
They have a similar problem where they want to sort the list except for the first and last element
Nice find. One more reason to have that possible with ZO_ComboBox alone.
 
10/17/15, 07:24 AM   #8
merlight
AddOn Author - Click to view addons
Join Date: Jul 2014
Posts: 671
Reviving because:
  1. sort by "name" is still hardcoded in ComboBoxSortHelper
  2. incorrect is-defined-tests of sortOrder (which may be ZO_SORT_ORDER_DOWN == false) are still there, only moved to ZO_ComboBox_Base:UpdateItems and ZO_ComboBox_Base:SetSortOrder
  3. found another such incorrect test in ZO_SortHeaderGroup:OnHeaderClicked
    Lua Code:
    1. function ZO_SortHeaderGroup:OnHeaderClicked(header, suppressCallbacks, forceReselect)
    2.     if self:IsEnabled() then
    3.         local resetSortDir = false
    4.         if forceReselect or not self:IsCurrentSelectedHeader(header) then
    5.             self:DeselectHeader()
    6.             resetSortDir = true
    7.         end
    8.  
    9.         -- this is wrong, initialDirection == false should be taken as valid value
    10.         self.sortDirection = resetSortDir and header.initialDirection or not self.sortDirection
    11. ...

    fixed:
    Lua Code:
    1. function ZO_SortHeaderGroup:OnHeaderClicked(header, suppressCallbacks, forceReselect)
    2.     if self:IsEnabled() then
    3.         if forceReselect or not self:IsCurrentSelectedHeader(header) then
    4.             self:DeselectHeader()
    5.             self.sortDirection = header.initialDirection
    6.         else
    7.             self.sortDirection = not self.sortDirection
    8.         end
    9. ...
 

ESOUI » Developer Discussions » Wish List » [outdated] ZO_ComboBox sort order


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off