Thread Tools Display Modes
09/04/15, 07:45 PM   #1
Argusus
AddOn Author - Click to view addons
Join Date: Sep 2014
Posts: 120
ZO_Templates ScrollTemplates

Hello,

Does anyone have recommendations for me change my Scroll lists in TradesMan? It looks like they have removed or deprecated the Filter ScrollList base I was relying on to build my addon. any feedback/suggestions are appreciated! below is the message i'm getting since the new update.

  Reply With Quote
09/04/15, 08:23 PM   #2
merlight
AddOn Author - Click to view addons
Join Date: Jul 2014
Posts: 671
You're either passing nil instead of proper list control to ZO_ScrollList_AddDataType, or it hasn't been initialized properly with ZO_ScrollList_Initialize.
  Reply With Quote
09/04/15, 08:30 PM   #3
merlight
AddOn Author - Click to view addons
Join Date: Jul 2014
Posts: 671
Ok, read some more.

In order to be used as ZO_SortFilterList, CustomerListContainer must contain a control named "$(parent)List" that inherits="ZO_ScrollList".

Delete all your X:New functions, they're not needed, and wrong. ZO_SortFilterList.New itself calls :Initialize, you don't want to call it a second time. Fix your :Initialize functions to call the base as the very first thing.
  Reply With Quote
09/04/15, 08:41 PM   #4
Argusus
AddOn Author - Click to view addons
Join Date: Sep 2014
Posts: 120
Originally Posted by merlight View Post
Ok, read some more.

In order to be used as ZO_SortFilterList, CustomerListContainer must contain a control named "$(parent)List" that inherits="ZO_ScrollList".

Delete all your X:New functions, they're not needed, and wrong. ZO_SortFilterList.New itself calls :Initialize, you don't want to call it a second time. Fix your :Initialize functions to call the base as the very first thing.
cool thanks for the information. So I should remove the calls in TradesMan when calling new? on line 1277 I have TRADESMAN.CustomerList = CustomerList:New() which then calls Initialize, then I have these for my x:New functions.


Code:
function CustomerList:New()
	local customers = ZO_SortFilterList.New(self, CustomerListContainer)
	customers:Initialize()
	return customers
end
  Reply With Quote
09/04/15, 08:58 PM   #5
merlight
AddOn Author - Click to view addons
Join Date: Jul 2014
Posts: 671
Remove the function CustomerList:New(), it's overriding the base with nothing "new" to add

TRADESMAN.CustomerList = CustomerList:New(CustomerListContainer)
will work just fine without it, because CustomerList is already defined as ZO_SortFilterList:Subclass(), so it will call the correct New and YOUR Initialize (that's why you need to call ZO_SortFilterList.Initialize from there)
  Reply With Quote
09/04/15, 09:17 PM   #6
circonian
AddOn Author - Click to view addons
Join Date: May 2014
Posts: 613
Example: (I combined your New & Initialize functions)
Lua Code:
  1. function CustomerList:New()
  2.     local manager = ZO_SortFilterList.New(self, CustomerListContainer)
  3.     manager.masterList = {}
  4.    
  5.     ZO_ScrollList_AddDataType(manager.list, 1, "CustomerUnitRow", 30, function(control, data) manager:SetupUnitRow(control, data) end)
  6.     ZO_ScrollList_EnableHighlight(manager.list, "ZO_ThinListHighlight")
  7.     manager.sortFunction = function(listEntry1, listEntry2) return ZO_TableOrderingFunction(listEntry1.data, listEntry2.data, manager.currentSortKey, CustomerList.SORT_KEYS, manager.currentSortOrder) end
  8.     manager.sortHeaderGroup:SelectHeaderByKey("name")
  9.     manager:RefreshData()
  10.    
  11.     return manager
  12. end
  13.  
  14. TRADESMAN.CustomerList = CustomerList:New()

Last edited by circonian : 09/04/15 at 09:21 PM.
  Reply With Quote
09/04/15, 10:09 PM   #7
Argusus
AddOn Author - Click to view addons
Join Date: Sep 2014
Posts: 120
Originally Posted by circonian View Post
Example: (I combined your New & Initialize functions)
Lua Code:
  1. function CustomerList:New()
  2.     local manager = ZO_SortFilterList.New(self, CustomerListContainer)
  3.     manager.masterList = {}
  4.    
  5.     ZO_ScrollList_AddDataType(manager.list, 1, "CustomerUnitRow", 30, function(control, data) manager:SetupUnitRow(control, data) end)
  6.     ZO_ScrollList_EnableHighlight(manager.list, "ZO_ThinListHighlight")
  7.     manager.sortFunction = function(listEntry1, listEntry2) return ZO_TableOrderingFunction(listEntry1.data, listEntry2.data, manager.currentSortKey, CustomerList.SORT_KEYS, manager.currentSortOrder) end
  8.     manager.sortHeaderGroup:SelectHeaderByKey("name")
  9.     manager:RefreshData()
  10.    
  11.     return manager
  12. end
  13.  
  14. TRADESMAN.CustomerList = CustomerList:New()
AWESOME!! thanks so much man! thats big time. I really appreciate.. I'm a Newb at Lua... just live in the asp.net world so i'm learning as I go... I really appreciate it! thanks for the quick resolution.
  Reply With Quote
09/04/15, 10:10 PM   #8
Argusus
AddOn Author - Click to view addons
Join Date: Sep 2014
Posts: 120
Originally Posted by merlight View Post
Remove the function CustomerList:New(), it's overriding the base with nothing "new" to add

TRADESMAN.CustomerList = CustomerList:New(CustomerListContainer)
will work just fine without it, because CustomerList is already defined as ZO_SortFilterList:Subclass(), so it will call the correct New and YOUR Initialize (that's why you need to call ZO_SortFilterList.Initialize from there)
thanks for the quick responses! I really appreciate it Mer!
  Reply With Quote
09/05/15, 06:03 AM   #9
merlight
AddOn Author - Click to view addons
Join Date: Jul 2014
Posts: 671
Should've posted more concrete code -- but it was way too late, sorry -- to show why overriding New isn't needed at all thanks to how it's written (it passes all arguments to Initialize).

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

This way CustomerListContainer is not hard-coded in the class, thus you could create multiple instances (on different container controls). Not really useful in your case, I know, but still cleaner IMO.

Another little suggestion that's good getting used to. In BuildMasterList(), don't create a new table, discarding the old one -- unless you have a million items in there and really want to free the memory and only insert a thousand -- just clear the existing table with
Lua Code:
  1. ZO_ClearNumericallyIndexedTable(self.masterList)
  Reply With Quote
09/05/15, 07:39 AM   #10
Argusus
AddOn Author - Click to view addons
Join Date: Sep 2014
Posts: 120
Originally Posted by merlight View Post
Should've posted more concrete code -- but it was way too late, sorry -- to show why overriding New isn't needed at all thanks to how it's written (it passes all arguments to Initialize).

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

This way CustomerListContainer is not hard-coded in the class, thus you could create multiple instances (on different container controls). Not really useful in your case, I know, but still cleaner IMO.

Another little suggestion that's good getting used to. In BuildMasterList(), don't create a new table, discarding the old one -- unless you have a million items in there and really want to free the memory and only insert a thousand -- just clear the existing table with
Lua Code:
  1. ZO_ClearNumericallyIndexedTable(self.masterList)
I really like this suggestion. I have been wanting to clean up tradesman for a while now. I think making a reusable constructor would be a step in the right direction. Below is a shorter version of my "BuildMasterList"

Code:
function CustomerList:New()
	local customers = ZO_SortFilterList.New(self, CustomerListContainer)
	
	customers.masterList = {}
	
 	ZO_ScrollList_AddDataType(customers.list, 1, "CustomerUnitRow", 30, function(control, data) customers:SetupUnitRow(control, data) end)
 	ZO_ScrollList_EnableHighlight(customers.list, "ZO_ThinListHighlight")	
 	customers.sortFunction = function(listEntry1, listEntry2) return ZO_TableOrderingFunction(listEntry1.data, listEntry2.data, customers.currentSortKey, CustomerList.SORT_KEYS, customers.currentSortOrder) end
	customers.sortHeaderGroup:SelectHeaderByKey("name")
	customers:RefreshData()
		
	return customers
end

function CustomerList:BuildMasterList()
	self.masterList = {}	
    	local transactions = TRADESMAN.savedVariables.Transactions
	table.insert(self.masterList, transactions)
    end		
end
Have you looked at the code for tradesman? I have 4-5 of these scroll lists, and basically the same code to create each except for the container control and the sort keys that are needed to be unique, then after that when buildmasterlist, I access the saved variables to populate the scroll lists. I wonder how I could have all of my scroll lists share the same initialization code but have unique sort keys, and build master list, passing in unique containers you explained well.

Last edited by Argusus : 09/05/15 at 08:23 AM.
  Reply With Quote
09/05/15, 08:34 AM   #11
merlight
AddOn Author - Click to view addons
Join Date: Jul 2014
Posts: 671
Originally Posted by Argusus View Post
I have 4-5 of these scroll lists, and basically the same code to create each except for the container control and the sort keys that are needed to be unique, then after that when buildmasterlist, I access the saved variables to populate the scroll lists. I wonder how I could have all of my scroll lists share the same initialization code but have unique sort keys, and build master list, passing in unique containers you explained well.
Well, they have different row control template, default sort header, vastly different BuildMasterList, I think they deserve being separate classes. You can move a few things to a common base, like FilterScrollList and SortScrollList which are identical, and derive your special classes from that base.

Lua Code:
  1. local StuffListBase = ZO_SortFilterList:Subclass()
  2. local CustomerList = StuffListBase:Subclass()
  3. local XTradeItemsList = StuffListBase:Subclass()
  4. ...

My/TheirTradeItemsList look like they could be merged. Just pass the things that differ as additional arguments to initialize, and store them in the instance.

Lua Code:
  1. function XTradeItemsList:Initialize(control, itemsKey)
  2.     StuffListBase.Initialize(self, control)
  3.     self.itemsKey = itemsKey
  4.     ...
  5. end
  6.  
  7. function XTradeItemsList:BuildMasterList()
  8.     ...
  9.     for key, itemObject in pairs(selectedTrade[self.itemsKey]) do
  10.         ...
  11.     end
  12. end
  13.  
  14. TRADESMAN.MyTradeItemsList = XTradeItemsList:New(MyTradeItemsContainer, "MyItems")
  15. TRADESMAN.TheirTradeItemsList = XTradeItemsList:New(TheirTradeItemsContainer, "TheirItems")
  Reply With Quote
09/05/15, 10:06 AM   #12
Argusus
AddOn Author - Click to view addons
Join Date: Sep 2014
Posts: 120
Originally Posted by merlight View Post
Well, they have different row control template, default sort header, vastly different BuildMasterList, I think they deserve being separate classes. You can move a few things to a common base, like FilterScrollList and SortScrollList which are identical, and derive your special classes from that base.

Lua Code:
  1. local StuffListBase = ZO_SortFilterList:Subclass()
  2. local CustomerList = StuffListBase:Subclass()
  3. local XTradeItemsList = StuffListBase:Subclass()
  4. ...

My/TheirTradeItemsList look like they could be merged. Just pass the things that differ as additional arguments to initialize, and store them in the instance.

Lua Code:
  1. function XTradeItemsList:Initialize(control, itemsKey)
  2.     StuffListBase.Initialize(self, control)
  3.     self.itemsKey = itemsKey
  4.     ...
  5. end
  6.  
  7. function XTradeItemsList:BuildMasterList()
  8.     ...
  9.     for key, itemObject in pairs(selectedTrade[self.itemsKey]) do
  10.         ...
  11.     end
  12. end
  13.  
  14. TRADESMAN.MyTradeItemsList = XTradeItemsList:New(MyTradeItemsContainer, "MyItems")
  15. TRADESMAN.TheirTradeItemsList = XTradeItemsList:New(TheirTradeItemsContainer, "TheirItems")
Cool, thank you! Let me look this over and get my head around it... I really appreciate this!
  Reply With Quote
09/05/15, 01:32 PM   #13
circonian
AddOn Author - Click to view addons
Join Date: May 2014
Posts: 613
One thing I want to point out to hopefully eliminate any confusion I may have caused (maybe I should have just stayed out of it & let him answer :P)

I know merlight kept saying don't overwrite CustomerList:New() ...but, yet that's exactly what I did.
It looks like we both did the same thing, but with a different approach.

Since:
Lua Code:
  1. CustomerList = ZO_SortFilterList:Subclass()
CustomerList already has a New() & an Initialize() function (from ZO_SortFilterList:Subclass()).

I overwrote the CustomerList:New() (from ZO_SortFilterList:Subclass()) function, but then called it in MY New() function.
I call the :New() function I created, which calls the original :New() function, which then calls the original Initialize() function so both the original :New() & :Initialize() both still run.
Lua Code:
  1. function CustomerList:New()
  2.    -- ZO_SortFilterList:New(...) is the function I'm overwriting
  3.    -- So I call it here
  4.    local manager = ZO_SortFilterList.New(self, CustomerListContainer)
  5. ...
  6. end

Merlight left the original CustomerList:New() function (from ZO_SortFilterList:Subclass()) and overwrote the CutomerList:Initialize() function, but then he manually called it in his Initialize()
He calls the Original :New() function, which automatically calls the :Initialize() function that he wrote and it calls the original :Initialize() function. So again both the original :New() & :Initialize() functions get ran.
Lua Code:
  1. function CustomerList:Initialize(control)
  2.    -- ZO_SortFilterList:Initialize() is the function he is overwriting
  3.    -- So he calls it here
  4.    ZO_SortFilterList.Initialize(self, control)
  5. ...
  6. end

He is right about the hard coding of CustomerListContainer in the code. I didn't think about it, but the same could have been accomplished this way by just passing it to the new function
Lua Code:
  1. function CustomerList:New(control)
  2.     local manager = ZO_SortFilterList.New(self, control)
  3. ...
  4. end
  5. TRADESMAN.CustomerList = CustomerList:New(CustomerListContainer)

Last edited by circonian : 09/05/15 at 01:52 PM.
  Reply With Quote

ESOUI » Developer Discussions » Lua/XML Help » ZO_Templates ScrollTemplates


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