@David-Healey Thanks for the clarification — that makes sense 
I understand now that drawPresetBrowserListItem overrides drawing for all columns, so everything has to be drawn manually.
I tried doing exactly that, but I still get the same behavior.
When I draw both the icon column and the text columns, the text becomes visible but the expansion icon disappears.
This is the code I tried:
lav.registerFunction("drawPresetBrowserListItem", function(g, obj)
{
var a = obj.area;
// Expansion icon column
if (obj.columnIndex == -1)
{
g.setColour(Colours.withAlpha(Colours.white, obj.hover ? 1.0 : 0.5));
if (lav.getImage(obj.text))
g.drawImage(obj.text, a, 0, 0);
return;
}
// Other columns (text)
g.setColour(Colours.withAlpha(Colours.white,
obj.selected ? 1.0 : (obj.hover ? 0.9 : 0.65)));
g.setFont("Default", obj.selected ? 15.0 : 14.0);
g.drawAlignedText(obj.text, a.reduced(8, 0), "left");
});
The result is:
Text in the other columns shows correctly
The expansion icon still does not appear
The icons are loaded like this:
inline function loadExpansionImagesIntoLaf(obj)
{
local expHandler = Engine.createExpansionHandler();
for (e in expHandler.getExpansionList())
{
local img = e.getWildcardReference("Icon.png");
if (isDefined(img))
obj.loadImage(img, e.getProperties().Name);
}
}
Am I misunderstanding what obj.text contains in the icon column?
Is there a specific property in obj that should be used to identify the expansion / library for the current row, instead of obj.text?
Thanks a lot for your help!