Thread Tools Display Modes
07/16/15, 09:39 PM   #1
kerb9729
AddOn Author - Click to view addons
Join Date: Apr 2014
Posts: 56
Setting colors in ZO_ScrollList list elements

Greetings fellow adventurers,

I'm hoping that one of you wise oracles can help me.
I've created a control based on ZO_ScrollList:

Code:
    -- Create a scrollList
    TP4_RIGHTPANE.ScrollList = WINDOW_MANAGER:CreateControlFromVirtual("$(parent)Tp4ScrollList", TP4_RIGHTPANE, "ZO_ScrollList")
    TP4_RIGHTPANE.ScrollList:SetDimensions(x, y-32)
    TP4_RIGHTPANE.ScrollList:SetAnchor(TOPLEFT, TP4_RIGHTPANE.Headers, BOTTOMLEFT, 0, 0)

    --
    -- Add a datatype to the scrollList
    --
    ZO_ScrollList_Initialize(TP4_RIGHTPANE.ScrollList)
    ZO_ScrollList_EnableHighlight(TP4_RIGHTPANE.ScrollList, "ZO_ThinListHighlight")
    ZO_ScrollList_AddDataType(TP4_RIGHTPANE.ScrollList, TP4_LOCATION_DATA, "Tp4Row", 23,
        function(control, data)
            control:GetNamedChild("Name"):SetText(data.playerName)
            control:GetNamedChild("Location"):SetText(data.zoneName)
        end
    )
Then I populate it with:

Code:
local function populateScrollList(listdata)
    local displayed = {}
    displayed[GetUnitName("player")] = 1
    local scrollData = ZO_ScrollList_GetDataList(TP4_RIGHTPANE.ScrollList)
    ZO_ClearNumericallyIndexedTable(scrollData)

    for k, player in ipairs(listdata) do
        if displayed[player.name] == nil then
            table.insert(scrollData, ZO_ScrollList_CreateDataEntry(TP4_LOCATION_DATA,
                {
                    playerName = player.name,
                    zoneName = player.zone
                }
                )
            )
            displayed[player.name] = 1
        end
    end
    ZO_ScrollList_Commit(TP4_RIGHTPANE.ScrollList)
end
This all works just dandy.

But my question is, what's the best way to colorize the text of the data elements?
It it possible to add text color properties when I call ZO_ScrollList_CreateDataEntry? Or should I encode the data beforehand somehow?

Thanks guys!
  Reply With Quote
07/17/15, 12:41 AM   #2
circonian
AddOn Author - Click to view addons
Join Date: May 2014
Posts: 613
If you have certain colors that you want to be the same for every row item, then you should do it in your row control template: "Tp4Row", as an example, this is part of the xml code for a row control template used in one of my addons. You can see where I set the color.
This example uses a simple label as the row control template.
Lua Code:
  1. ZO_ScrollList_AddDataType(scrollList, ROW_TYPE_ID, "Click4InfoRowControl", BUTTON_HEIGHT, setupDataRow)
xml Code:
  1. <Controls>
  2. <!-- This is the rowControl for the zo_scrollList -->
  3.         <Label name="Click4InfoRowControl" inherits="ZO_SelectableLabel" mouseEnabled="true" virtual="true" font="ZoFontWinH4" color="INTERFACE_COLOR_TYPE_TEXT_COLORS:INTERFACE_TEXT_COLOR_NORMAL" horizontalAlignment="left" verticalAlignment="center" wrapMode="ELLIPSIS"  >
  4.             <Dimensions y="30" />
  5.           ... other code ...
  6.         </Label>


Or if you have multiple controls inside of the template you can just set each color however you like for each control individually inside the template:
Lua Code:
  1. ZO_ScrollList_AddDataType(self.scrollList, ROW_TYPE_ID, "WayPointButton", BUTTON_HEIGHT, setupDataRow)
xml Code:
  1. <!-- This is the rowControl for the zo_scrollList -->
  2.         <Control name="WayPointButton" virtual="true" clampedToScreen="false" mouseEnabled="true" movable="false" hidden="false" layer="2" level="0" tier="0" allowBringToTop="true" alpha="1" >
  3. <!-- ... lots of other code...-->
  4. <!-- notice color being set for this label -->
  5.                 <Label name="$(parent)NameLabel" font="ZoFontAnnounceSmall" color="ffffff" wrapMode="ELLIPSIS" text="" verticalAlignment="CENTER" horizontalAlignment="LEFT" alpha="1" layer="2" level="0" tier="0" >
  6.                     <Dimensions x="300" y="50" />
  7.                     <Anchor point="TOPLEFT" relativeTo="$(parent)TextureBG" relativePoint="TOPRIGHT" offsetX="0" offsetY="0"/>
  8.                     <Anchor point="BOTTOMRIGHT" relativeTo="$(parent)" relativePoint="BOTTOMRIGHT" offsetX="0" offsetY="0"/>
  9.                 </Label>
  10.                
  11. <!-- notice a different color being set for this label -->
  12.                 <Label name="$(parent)LevelLabel" font="ZoFontAnnounceSmall" color="FFA500" wrapMode="ELLIPSIS" text="" verticalAlignment="CENTER" horizontalAlignment="LEFT" alpha="1" layer="2" level="0" tier="1" >
  13.                     <Dimensions x="30" y="25" />
  14.                     <Anchor point="TOPLEFT" relativeTo="$(parent)TextureBG" relativePoint="TOPLEFT" offsetX="5" offsetY="5"/>
  15.                 </Label>

If your "Tp4Row" was not done in xml, thats ok, it doesn't matter. That was just some code I already had written so it was easy to copy & paste as an example. If your row control template is written in lua, just use :SetColor(...) or whatever to make whatever changes you want to the template.

Last edited by circonian : 07/17/15 at 12:59 AM.
  Reply With Quote
07/17/15, 01:38 AM   #3
votan
 
votan's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2014
Posts: 577
In addition to what circonian said already:
This is the signature of that function:
--Adds a new control type for the list to handle. It must maintain a consistent size.
--@typeId - A unique identifier to give to CreateDataEntry when you want to add an element of this type.
--@templateName - The name of the virtual control template that will be used to hold this data
--@height - The control height
--@setupCallback - The function that will be called when a control of this type becomes visible. Signature: setupCallback(control, data)
--@dataTypeSelectSound - An optional sound to play when a row of this data type is selected.
--@resetControlCallback - An optional callback when the datatype control gets reset.
function ZO_ScrollList_AddDataType(self, typeId, templateName, height, setupCallback, hideCallback, dataTypeSelectSound, resetControlCallback)

So, you can do "everything" with control and child-controls based on data, including :SetColor. This way all is "on demand", spreading CPU load. Keep your scroll-list-data-table as bare/raw as possible: e.g. just passing player.

PS: This way you may be able to refresh the scroll-list without re-building the data-table just by calling:
ZO_ScrollList_RefreshVisible(yourScrollListControl)

--updates the layout of visible controls
--data: optionally allows you to only update the control backed by the specified data table
--overrideSetupCallback: optionally allows you to call this function instead of the normal setup function if you only need to do a very specific update
function ZO_ScrollList_RefreshVisible(self, data, overrideSetupCallback)
  Reply With Quote
07/17/15, 02:40 PM   #4
kerb9729
AddOn Author - Click to view addons
Join Date: Apr 2014
Posts: 56
Guys -

As always, thanks for the pointers!

Creating an addon has certainly been an education.
  Reply With Quote
07/17/15, 04:39 PM   #5
kerb9729
AddOn Author - Click to view addons
Join Date: Apr 2014
Posts: 56
My controls look like this:



and here's the xml:
Code:
<GuiXml>
    <Controls>
        <Control name="Tp4Row" virtual="true">
            <Anchor point="RIGHT" relativeTo="$(parent)" />
            <Dimensions y="23"/>
            <Controls>
                <Label name="$(parent)Name" inherits="ZO_SelectableLabel" font="ZoFontHeader" wrapMode="TRUNCATE">
                    <Dimensions x="115" y="32"/>
                    <Anchor point="TOPLEFT" offsetX="0"/>
                    <OnMouseUp>nameOnMouseUp(self, button, upInside)</OnMouseUp>
                    <!--OnClicked>nameOnClicked(self, button)</OnClicked> -->
                </Label>
                <Label name="$(parent)Location" inherits="ZO_SelectableLabel" font="ZoFontHeader" wrapMode="TRUNCATE">
                    <Dimensions x="150" y="32"/>
                    <Anchor point="LEFT" relativeTo="$(parent)Name" relativePoint="RIGHT" offsetX="10"/>
                </Label>
            </Controls>
        </Control>
        <TopLevelControl name="Teleporter4">
            <OnInitialized>
                Tp4_OnInitialized()
            </OnInitialized>
        </TopLevelControl>
    </Controls>
</GuiXml>
If I understand correctly from your examples, I can set the text color for the entire thing by setting the attribute in Tp4Row (the read area.) Note* looking at this now, Tp4Row seems like a terrible name =P.
Or I can set the text color of all of the text in either of Tp4Row's subsections "Name" (blue)or "Location" (green, which oddly now has the label "ZONE") by configuring one of those.

But what I'm really after is to color one element in the list (e.g. @ApothicDark) if he happens to be in my friends list. Or perhaps a different color if he's in my party. But leave the rest of the names default white.

(As I was typing this, a lightbulb might have come on over my head, however dim it may be)
To do what I want, I think I need to add multiple datatypes. e.g.

Code:
ZO_ScrollList_AddDataType(TP4_RIGHTPANE.ScrollList, TP4_LOCATION_DATA, "Tp4Row", 23,
        function(control, data)
            control:GetNamedChild("Name"):SetText(data.playerName)
            control:GetNamedChild("Location"):SetText(data.zoneName)
        end
    )

ZO_ScrollList_AddDataType(TP4_RIGHTPANE.ScrollList, TP4_LOCATION_DATA_FRIEND, "Tp4Row", 23,
        function(control, data)
            control:GetNamedChild("Name"):SetText(data.playerName)
            control:GetNamedChild("Location"):SetText(data.zoneName)
            -- add code down here to modify "Name" and /or "Location" color for TP4_LOCATION_DATA_FRIEND
        end
    )
and then differentiate between the two by supplying different arguments TP4_LOCATION_DATA or TP4_LOCATION_DATA_FRIEND to ZO_ScrollList_CreateDataEntry e.g.

Code:
          table.insert(scrollData, ZO_ScrollList_CreateDataEntry(TP4_LOCATION_DATA_FRIEND,
                {
                    playerName = player.name,
                    zoneName = player.zone
                }
                )
            )

Thanks guys, for bearing with me! Kinda figuring this stuff out as I go. God I'm such a doofus.
I'm off to test! (and rename some variables so they make sense)

edit 2 - I think this is what Votan was trying to get across, I just didn't grok what he meant

Last edited by kerb9729 : 07/17/15 at 04:59 PM. Reason: clarity
  Reply With Quote
07/17/15, 05:23 PM   #6
merlight
AddOn Author - Click to view addons
Join Date: Jul 2014
Posts: 671
Multiple datatypes are meant for... well... displaying multiple types of data; not a hard rule of course, but often it's for mixing different things, with different row templates, different data fields etc.

You can just use your single datatype setup callback and decide the color there. That way you also won't need to rebuild the list when you add/remove a friend, ZO_ScrollList_RefreshVisible will suffice.

Lua Code:
  1. ZO_ScrollList_AddDataType(TP4_RIGHTPANE.ScrollList, TP4_LOCATION_DATA, "Tp4Row", 23,
  2.         function(control, data)
  3.             local nameLabel = control:GetNamedChild("Name")
  4.             nameLabel:SetText(data.playerName)
  5.             control:GetNamedChild("Location"):SetText(data.zoneName)
  6.             if IsFriend(data.playerName) then
  7.                 nameLabel:SetColor(0.5, 1, 0, 1)
  8.             else
  9.                 nameLabel:SetColor(ZO_NORMAL_TEXT:UnpackRGBA())
  10.             end
  11.         end
  12.     )

tip 1: use [ highlight="lua" ] for syntax highlighting (the blue Lua icon pastes that)
tip 2: don't call ZO_ScrollList_Initialize, the ZO_ScrollList template does it already
  Reply With Quote
07/17/15, 05:30 PM   #7
circonian
AddOn Author - Click to view addons
Join Date: May 2014
Posts: 613
Originally Posted by kerb9729 View Post
(As I was typing this, a lightbulb might have come on over my head, however dim it may be)
To do what I want, I think I need to add multiple datatypes. e.g.
No, you don't want to do that. If your wanting different colors for different rows (to color a friend or whatever) then do it the way votan suggested, do it in the rowSetupCallback function...thats the one you defined here:
Lua Code:
  1. ZO_ScrollList_AddDataType(TP4_RIGHTPANE.ScrollList, TP4_LOCATION_DATA, "Tp4Row", 23,
  2.         function(control, data)
  3.             control:GetNamedChild("Name"):SetText(data.playerName)
  4.             control:GetNamedChild("Location"):SetText(data.zoneName)
  5.         end
  6.     )

The way I suggested, doing it in the the row template is better if your wanting them all (or most) to have the same values. Like setting the default color for all of the items or whatever. If your wanting to individually change some rows or have something that needs to be set up differently for different rows based on some conditions you want to do it in the rowSetupCallback.


I would separate it to make it all easy to read, the code is probably going to grow, so maybe something like this:
Lua Code:
  1. -- throw this in your code somewhere
  2. local function SetupRowCallback(control, data)
  3.    local nameControl = control:GetNamedChild("Name")
  4.    local locationControl = control:GetNamedChild("Location")
  5.  
  6.    nameControl:SetText(data.playerName)
  7.    locationControl:SetText(data.zoneName)
  8.  
  9.   -- do whatever check to see if that person is on your friends list or in your group
  10.    local playerName = data.playerName
  11.    if ....... then
  12.       nameControl:SetColor(..whatever..)
  13.       locationControl:SetColor(..whatever..)
  14. end
  15.  
  16. -- and set SetupRowCallback here instead of actually defining the function here:
  17. ZO_ScrollList_AddDataType(TP4_RIGHTPANE.ScrollList, TP4_LOCATION_DATA, "Tp4Row", 23, SetupRowCallback)

Last edited by circonian : 07/17/15 at 05:34 PM.
  Reply With Quote
07/17/15, 09:39 PM   #8
kerb9729
AddOn Author - Click to view addons
Join Date: Apr 2014
Posts: 56


You guys are awesome. Virtual beers all around!

I noticed that although name highlighting now works (THANKS everyone!), if I mouse over the player name, the text color gets set back to default. What appears to be happening is that the item is highlighted in mouseover and then set back to the default color on mouseoff.

I found where I set ZO_ScrollList_EnableHighlight in my code, but when I comment it out I still get highlighting.

Now I know why all the interface programmers I know are bald.
  Reply With Quote
07/18/15, 05:21 AM   #9
merlight
AddOn Author - Click to view addons
Join Date: Jul 2014
Posts: 671
Originally Posted by kerb9729 View Post
I found where I set ZO_ScrollList_EnableHighlight in my code, but when I comment it out I still get highlighting.
That is for list-row-level highlight, e.g. the blue row background you see in inventory.

Originally Posted by kerb9729 View Post
I noticed that although name highlighting now works (THANKS everyone!), if I mouse over the player name, the text color gets set back to default. What appears to be happening is that the item is highlighted in mouseover and then set back to the default color on mouseoff.
That comes from "ZO_SelectableLabel" your label inherits from. I haven't noticed that before. In this case, instead of calling nameLabel:SetColor() directly, you have to use ZO_SelectableLabel_SetNormalColor
Lua Code:
  1. -- define this somewhere above the setup callback function, so that it's not re-created every time
  2. local friendColor = ZO_ColorDef:New(0.5, 1, 0, 1)
  3.  
  4. if IsFriend(data.playerName) then
  5.     ZO_SelectableLabel_SetNormalColor(nameLabel, friendColor)
  6. else
  7.     ZO_SelectableLabel_SetNormalColor(nameLabel, ZO_NORMAL_TEXT)
  8. end
  Reply With Quote
07/18/15, 10:20 AM   #10
kerb9729
AddOn Author - Click to view addons
Join Date: Apr 2014
Posts: 56
Originally Posted by merlight View Post
That is for list-row-level highlight, e.g. the blue row background you see in inventory.


That comes from "ZO_SelectableLabel" your label inherits from. I haven't noticed that before. In this case, instead of calling nameLabel:SetColor() directly, you have to use ZO_SelectableLabel_SetNormalColor
Lua Code:
  1. -- define this somewhere above the setup callback function, so that it's not re-created every time
  2. local friendColor = ZO_ColorDef:New(0.5, 1, 0, 1)
  3.  
  4. if IsFriend(data.playerName) then
  5.     ZO_SelectableLabel_SetNormalColor(nameLabel, friendColor)
  6. else
  7.     ZO_SelectableLabel_SetNormalColor(nameLabel, ZO_NORMAL_TEXT)
  8. end

It would have taken me forever to figure all of that out on my own. I did trace the problem to ZO_SelectableLabel by working my way backward from the xml definition, but that's as far as I got last night. Thanks!
  Reply With Quote
07/19/15, 10:16 PM   #11
kerb9729
AddOn Author - Click to view addons
Join Date: Apr 2014
Posts: 56
Ok, last thing -

How do I configure tooltips to appear when I mouse over my nicely colored names?

I got it working for the sort controls, but the scrolllist items are different.
  Reply With Quote
07/20/15, 01:29 AM   #12
votan
 
votan's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2014
Posts: 577
Originally Posted by kerb9729 View Post
Ok, last thing -

How do I configure tooltips to appear when I mouse over my nicely colored names?

I got it working for the sort controls, but the scrolllist items are different.
Again, the row setup function is a good place to do that:
local function setupDataRow(rowControl, rowData)
...
rowControl:SetHandler("OnMouseEnter", onMouseEnterFunction)
rowControl:SetHandler("OnMouseExit", onMouseExitFunction)

If your templateControl, has OnMouse* handlers already, you have to chain them with yours, without chaining them over and over again. So do not use ZO_PreHookHandler in setupDataRow without additional checks.
One way could be to find out what the current handlers are (by looking into the source), and call them in your handlers.
Many other ways you could do.
  Reply With Quote
07/20/15, 04:51 AM   #13
merlight
AddOn Author - Click to view addons
Join Date: Jul 2014
Posts: 671
ZO_SelectableLabel has default OnMouseEnter/Exit handlers for mouse-over highlight. You can override them in XML, setup tooltip and call the ZO handlers yourself.
XML Code:
  1. <Label name="$(parent)Name" inherits="ZO_SelectableLabel" font="ZoFontHeader" wrapMode="TRUNCATE">
  2.     <Dimensions x="115" y="32"/>
  3.     <Anchor point="TOPLEFT" offsetX="0"/>
  4.     <OnMouseEnter>
  5.         ZO_SelectableLabel_OnMouseEnter(self)
  6.         if self.tooltipText then
  7.             InitializeTooltip(InformationTooltip, self, LEFT, -5, 0, RIGHT)
  8.             SetTooltipText(InformationTooltip, self.tooltipText)
  9.         end
  10.     </OnMouseEnter>
  11.     <OnMouseExit>
  12.         ZO_SelectableLabel_OnMouseExit(self)
  13.         if self.tooltipText then
  14.             ClearTooltip(InformationTooltip)
  15.         end
  16.     </OnMouseExit>
  17. </Label>

And in your row setup function, set nameLabel.tooltipText = "something"
  Reply With Quote
07/20/15, 08:13 AM   #14
kerb9729
AddOn Author - Click to view addons
Join Date: Apr 2014
Posts: 56
Originally Posted by merlight View Post
ZO_SelectableLabel has default OnMouseEnter/Exit handlers for mouse-over highlight. You can override them in XML, setup tooltip and call the ZO handlers yourself.
XML Code:
  1. <Label name="$(parent)Name" inherits="ZO_SelectableLabel" font="ZoFontHeader" wrapMode="TRUNCATE">
  2.     <Dimensions x="115" y="32"/>
  3.     <Anchor point="TOPLEFT" offsetX="0"/>
  4.     <OnMouseEnter>
  5.         ZO_SelectableLabel_OnMouseEnter(self)
  6.         if self.tooltipText then
  7.             InitializeTooltip(InformationTooltip, self, LEFT, -5, 0, RIGHT)
  8.             SetTooltipText(InformationTooltip, self.tooltipText)
  9.         end
  10.     </OnMouseEnter>
  11.     <OnMouseExit>
  12.         ZO_SelectableLabel_OnMouseExit(self)
  13.         if self.tooltipText then
  14.             ClearTooltip(InformationTooltip)
  15.         end
  16.     </OnMouseExit>
  17. </Label>

And in your row setup function, set nameLabel.tooltipText = "something"
I swear I seached google (and the wiki) for ZO_SelectableLabel, and all I found was this thread!
I figured there must be onmouse functions.
Where did you find the info on the ZO_SelectableLabel_OnmouseXX functions? I even "zgoo mouse"'ed until the game crashed (several times over).

(Actually I just checked ...thought I might be going insane... and I see that Circonian uploaded a new library for scrolllists. Woot! Not that I'm about to change anything now..)

As always, thanks to all of you for your help.
  Reply With Quote
07/20/15, 08:18 AM   #15
merlight
AddOn Author - Click to view addons
Join Date: Jul 2014
Posts: 671
http://www.esoui.com/forums/showpost...3&postcount=72
  Reply With Quote
07/20/15, 12:53 PM   #16
circonian
AddOn Author - Click to view addons
Join Date: May 2014
Posts: 613
Originally Posted by kerb9729 View Post
I swear I seached google (and the wiki) for ZO_SelectableLabel, and all I found was this thread!
Where did you find the info on the ZO_SelectableLabel_OnmouseXX functions? I even "zgoo mouse"'ed until the game crashed (several times over).
Yeah, you wont find thos by zgoo'n controls. I'm sure there are plenty of other good programs, but I use Total Commander (its free). It allows you to select a file or folder and you can search for text within all of the files in that folder. So to find things I just select the esoui folder (from the link that merlight posted) then search for ZO_SelectableLabel & it will tell you every file it appears in. Then you have to look through them all to find whatever your looking for. For example ZO_SelectableLabel is defined in esoui\libraries\zo_templates\windowtemplates.xml, which is where you find that it calls
Lua Code:
  1. <OnInitialized>
  2.     ZO_SelectableLabel_OnInitialized(self)
  3. </OnInitialized>
  4.  
  5. <OnMouseEnter>
  6.     ZO_SelectableLabel_OnMouseEnter(self)
  7. </OnMouseEnter>
  8. <OnMouseExit>
  9.     ZO_SelectableLabel_OnMouseExit(self)
  10. </OnMouseExit>

Then if you wanted to know exactly what those functions do, just search the esoui folder again for those function names & look through whatever files they show up in until you find the one they are defined in & look at the code.

Last edited by circonian : 07/20/15 at 12:55 PM.
  Reply With Quote

ESOUI » Developer Discussions » General Authoring Discussion » Setting colors in ZO_ScrollList list elements


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