Thread Tools Display Modes
10/11/14, 03:40 PM   #1
Argusus
AddOn Author - Click to view addons
Join Date: Sep 2014
Posts: 120
ZO_Helpers

I saw in Zgoo that there was a "Zo_BinarySearch" is there anywhere to find more docs on this or example uses?
  Reply With Quote
10/11/14, 04:24 PM   #2
merlight
AddOn Author - Click to view addons
Join Date: Jul 2014
Posts: 671
I remember when I wanted to use it I read the code and concluded it was broken. So I wrote my own. Well, it might be me having a bad day and reading the code wrong.

But even if it actually worked, it's badly designed. Unlike table.sort, which expects a comparator that takes 2 arguments and returns a boolean (basically operator '<'; you need to have a sorted table in order to use binary search), zo_binarysearch expects a comparator that takes 3 arguments and returns numeric difference (similar to perl's operator '<=>'; the third argument is index, which is totally irrelevant, but they still use it in their default broken comparator instead of the right-hand value). So in the end, you'd need to write two comparators - one for sorting and another for searching - awful design.

Last edited by merlight : 10/11/14 at 04:30 PM.
  Reply With Quote
10/11/14, 04:36 PM   #3
Argusus
AddOn Author - Click to view addons
Join Date: Sep 2014
Posts: 120
Originally Posted by merlight View Post
I remember when I wanted to use it I read the code and concluded it was broken. So I wrote my own. Well, it might be me having a bad day and reading the code wrong.

But even if it actually worked, it's badly designed. Unlike table.sort, which expects a comparator that takes 2 arguments and returns a boolean (basically operator '<'; you need to have a sorted table in order to use binary search), zo_binarysearch expects a comparator that takes 3 arguments and returns numeric difference (similar to perl's operator '<=>'; the third argument is index, which is totally irrelevant, but they still use it in their default broken comparator instead of the right-hand value). So in the end, you'd need to write two comparators - one for sorting and another for searching - awful design.
Ah, doesn't surprise me... too much mystery in the addon world right now. The post really relates to me wanting to sort the "masterList" alphabetically by a column when the BuildMasterList is called. it doesn't seem to be doing this by default so maybe i'm missing something there. I was thinking I could sort the table THEN add the items to the masterList object so it sorted by my first column (UnitName) by default.
  Reply With Quote
10/11/14, 05:02 PM   #4
merlight
AddOn Author - Click to view addons
Join Date: Jul 2014
Posts: 671
You don't need to sort anything in BuildMasterList. There's SortScrollList for that, it's called after the list is filtered to sort only items that pass the filter; and also when sort order changes, the list is not rebuilt, just sorted again. I'm looking into SLE and it looks like everything's in place.

Try this in UnitList:Initialize():
Lua Code:
  1. units.sortHeaderGroup:SelectHeaderByKey("name", ZO_SortHeaderGroup.SUPPRESS_CALLBACKS)

edited: wrong member name

Last edited by merlight : 10/11/14 at 05:04 PM.
  Reply With Quote
10/11/14, 05:07 PM   #5
Argusus
AddOn Author - Click to view addons
Join Date: Sep 2014
Posts: 120
Originally Posted by merlight View Post
You don't need to sort anything in BuildMasterList. There's SortScrollList for that, it's called after the list is filtered to sort only items that pass the filter; and also when sort order changes, the list is not rebuilt, just sorted again. I'm looking into SLE and it looks like everything's in place.

Try this in UnitList:Initialize():
Lua Code:
  1. units.sortHeaderGroup:SelectHeaderByKey("name", ZO_SortHeaderGroup.SUPPRESS_CALLBACKS)

edited: wrong member name
Code:
function UnitList:Initialize()
 	self.masterList = {}
 	ZO_ScrollList_AddDataType(self.list, 1, "UnitRow", 30, function(control, data) self:SetupUnitRow(control, data) end)
 	ZO_ScrollList_EnableHighlight(self.list, "ZO_ThinListHighlight")	
 	self.sortFunction = function(listEntry1, listEntry2) return ZO_TableOrderingFunction(listEntry1.data, listEntry2.data, self.currentSortKey, UnitList.SORT_KEYS, self.currentSortOrder) end
	self:RefreshData()
end
My Current code looks like the attached image, should I put this at the end of the method or where?
Attached Thumbnails
Click image for larger version

Name:	example.png
Views:	585
Size:	11.7 KB
ID:	488  
  Reply With Quote
10/11/14, 05:29 PM   #6
merlight
AddOn Author - Click to view addons
Join Date: Jul 2014
Posts: 671
I should read more carefully before pasting lines from different places. Now I think it should not suppress the callback, because it sets currentSortKey and currentSortOrder, which are then used in sortFunction.

I'd place it right before RefreshData call, without SUPPRESS_CALLBACK:

Lua Code:
  1. function UnitList:Initialize()
  2.     self.masterList = {}
  3.     ZO_ScrollList_AddDataType(self.list, 1, "UnitRow", 30, function(control, data) self:SetupUnitRow(control, data) end)
  4.     ZO_ScrollList_EnableHighlight(self.list, "ZO_ThinListHighlight")   
  5.     self.sortFunction = function(listEntry1, listEntry2) return ZO_TableOrderingFunction(listEntry1.data, listEntry2.data, self.currentSortKey, UnitList.SORT_KEYS, self.currentSortOrder) end
  6.     self.sortHeaderGroup:SelectHeaderByKey("name")
  7.     self:RefreshData()
  8. end

I'm still wondering how it could work without setting a sort key. I'd expect it to throw a "nil used as table key" error when there are 2 or more items in the list.
  Reply With Quote
10/12/14, 09:37 AM   #7
Argusus
AddOn Author - Click to view addons
Join Date: Sep 2014
Posts: 120
Originally Posted by merlight View Post
I should read more carefully before pasting lines from different places. Now I think it should not suppress the callback, because it sets currentSortKey and currentSortOrder, which are then used in sortFunction.

I'd place it right before RefreshData call, without SUPPRESS_CALLBACK:

Lua Code:
  1. function UnitList:Initialize()
  2.     self.masterList = {}
  3.     ZO_ScrollList_AddDataType(self.list, 1, "UnitRow", 30, function(control, data) self:SetupUnitRow(control, data) end)
  4.     ZO_ScrollList_EnableHighlight(self.list, "ZO_ThinListHighlight")   
  5.     self.sortFunction = function(listEntry1, listEntry2) return ZO_TableOrderingFunction(listEntry1.data, listEntry2.data, self.currentSortKey, UnitList.SORT_KEYS, self.currentSortOrder) end
  6.     self.sortHeaderGroup:SelectHeaderByKey("name")
  7.     self:RefreshData()
  8. end

I'm still wondering how it could work without setting a sort key. I'd expect it to throw a "nil used as table key" error when there are 2 or more items in the list.
Worked like a charm! thank you.
  Reply With Quote
10/12/14, 10:17 AM   #8
Argusus
AddOn Author - Click to view addons
Join Date: Sep 2014
Posts: 120
Originally Posted by merlight View Post
I should read more carefully before pasting lines from different places. Now I think it should not suppress the callback, because it sets currentSortKey and currentSortOrder, which are then used in sortFunction.

I'd place it right before RefreshData call, without SUPPRESS_CALLBACK:

Lua Code:
  1. function UnitList:Initialize()
  2.     self.masterList = {}
  3.     ZO_ScrollList_AddDataType(self.list, 1, "UnitRow", 30, function(control, data) self:SetupUnitRow(control, data) end)
  4.     ZO_ScrollList_EnableHighlight(self.list, "ZO_ThinListHighlight")   
  5.     self.sortFunction = function(listEntry1, listEntry2) return ZO_TableOrderingFunction(listEntry1.data, listEntry2.data, self.currentSortKey, UnitList.SORT_KEYS, self.currentSortOrder) end
  6.     self.sortHeaderGroup:SelectHeaderByKey("name")
  7.     self:RefreshData()
  8. end

I'm still wondering how it could work without setting a sort key. I'd expect it to throw a "nil used as table key" error when there are 2 or more items in the list.
is there a "descending" version of that by chance?
  Reply With Quote
10/12/14, 11:00 AM   #9
Garkin
 
Garkin's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 832
Originally Posted by skobyjay View Post
is there a "descending" version of that by chance?
sort order is the last argument passed to the:
ZO_TableOrderingFunction(entry1, entry2, sortKey, sortKeys, sortOrder)

sortOrder can be either ZO_SORT_ORDER_UP (true) or ZO_SORT_ORDER_DOWN (false)

In the ScrollListExample sort order could be set directly:
lua Code:
  1. self.sortOrder = ZO_SORT_ORDER_DOWN
or using the OnSortHeaderClicked(key, order) method inherited from the main class ZO_SortFilterList:
lua Code:
  1. self:OnSortHeaderClicked("name", ZO_SORT_ORDER_DOWN)


Changed code to use direct access to sort order:
lua Code:
  1. function UnitList:Initialize()
  2.     self.masterList = {}
  3.     ZO_ScrollList_AddDataType(self.list, 1, "UnitRow", 30, function(control, data) self:SetupUnitRow(control, data) end)
  4.     ZO_ScrollList_EnableHighlight(self.list, "ZO_ThinListHighlight")
  5.     self.currentSortKey = "name"
  6.     self.currentSortOrder = ZO_SORT_ORDER_DOWN
  7.     self.sortFunction = function(listEntry1, listEntry2) return ZO_TableOrderingFunction(listEntry1.data, listEntry2.data, self.currentSortKey, UnitList.SORT_KEYS, self.currentSortOrder) end
  8.     self:RefreshData()
  9. end

Changed code to use OnSortHeaderClicked:
lua Code:
  1. function UnitList:Initialize()
  2.     self.masterList = {}
  3.     ZO_ScrollList_AddDataType(self.list, 1, "UnitRow", 30, function(control, data) self:SetupUnitRow(control, data) end)
  4.     ZO_ScrollList_EnableHighlight(self.list, "ZO_ThinListHighlight")
  5.     self.sortFunction = function(listEntry1, listEntry2) return ZO_TableOrderingFunction(listEntry1.data, listEntry2.data, self.currentSortKey, UnitList.SORT_KEYS, self.currentSortOrder) end
  6.     self:SetLockedForUpdates(true) --lock for updates, so list will be refreshed only once
  7.     self:OnSortHeaderClicked("name", ZO_SORT_ORDER_DOWN)
  8.     self:RefreshData()
  9.     self:SetLockedForUpdates(false) --when unlocked, all pending refresh functions will be called
  10. end

Last edited by Garkin : 10/12/14 at 11:52 AM.
  Reply With Quote
10/12/14, 11:07 AM   #10
Argusus
AddOn Author - Click to view addons
Join Date: Sep 2014
Posts: 120
Originally Posted by Garkin View Post
sort order is the last argument passed to the:
ZO_TableOrderingFunction(entry1, entry2, sortKey, sortKeys, sortOrder)

sortOrder can be either ZO_SORT_ORDER_UP (true) or ZO_SORT_ORDER_DOWN (false)
if i change it there does that break the sort for the headers? I just want a "default" decending sort. The code below gives me asc sorting, is there a "decending" equivalent of the statement below I can use in the Initialize method.

Code:
self.sortHeaderGroup:SelectHeaderByKey("name")
  Reply With Quote
10/12/14, 11:51 AM   #11
Garkin
 
Garkin's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 832
I have edited my post to add some sample code. Descending order will be probably ZO_SORT_ORDER_DOWN.
  Reply With Quote
10/12/14, 01:08 PM   #12
Argusus
AddOn Author - Click to view addons
Join Date: Sep 2014
Posts: 120
Originally Posted by Garkin View Post
I have edited my post to add some sample code. Descending order will be probably ZO_SORT_ORDER_DOWN.
great, I will give that a shot! thanks.
  Reply With Quote
10/12/14, 04:37 PM   #13
merlight
AddOn Author - Click to view addons
Join Date: Jul 2014
Posts: 671
I did not suggest direct assignment because I was not sure the headers control would not get confused.

Originally Posted by skobyjay View Post
The code below gives me asc sorting, is there a "decending" equivalent of the statement below I can use in the Initialize method.

Code:
self.sortHeaderGroup:SelectHeaderByKey("name")
SelectHeaderByKey calls the same handler that's called when you click a header. If you click the same header again, it alternates between ascending/descending order.
Lua Code:
  1. -- setup sortHeaderGroup to order by name, without telling the owner (suppress callbacks)
  2. self.sortHeaderGroup:SelectHeaderByKey("name", ZO_SortHeaderGroup.SUPPRESS_CALLBACKS)
  3. -- switch to descending order and tell the owner
  4. self.sortHeaderGroup:SelectHeaderByKey("name")
  Reply With Quote
10/12/14, 09:00 PM   #14
Argusus
AddOn Author - Click to view addons
Join Date: Sep 2014
Posts: 120
Originally Posted by Garkin View Post
I have edited my post to add some sample code. Descending order will be probably ZO_SORT_ORDER_DOWN.
Looks like the XML defintion of the ZO_SORT_ORDER_DOWN is honored when the sort is called. Via self.sortHeaderGroup:SelectHeaderByKey("name")
  Reply With Quote
10/13/14, 05:38 AM   #15
merlight
AddOn Author - Click to view addons
Join Date: Jul 2014
Posts: 671
Originally Posted by skobyjay View Post
Looks like the XML defintion of the ZO_SORT_ORDER_DOWN is honored when the sort is called. Via self.sortHeaderGroup:SelectHeaderByKey("name")
You nailed it. I didn't expect that to be set in the XML.

Lua Code:
  1. ZO_SortHeader_Initialize(self, "Name", "name", ZO_SORT_ORDER_UP, TEXT_ALIGN_LEFT, "ZoFontGameLargeBold")

ZO_SortHeader_Initialize is certainly the best place to set the default order. That way when you click on another header, and later go back to Name, it'll use your desired default.
  Reply With Quote

ESOUI » Developer Discussions » Lua/XML Help » ZO_Helpers


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