listCOMP feedback

Hey, for the past couple of months I’ve been extensively using listCOMP and gathered some feedback that I wanted to share.

First of all let me tell you about my approach to using it: I have built a system that vaguely resembles html/css. Meaning every cell of a listCOMP has a python object associated with it, and when listCOMP emits onInitCell callback I’m storing attribs to my custom object to be able to dictate the look of the cell based on the settings of this python object (sorry, can’t share the code because it’s very hard to understand without context, our system is pretty advanced.) So in the end I was able to make it work for me, but I had so many head scratching moments during these times. And without having a proper debugger some things took me a ridiculous amount of time to figure out. So in the end I thought I should share some feedback on using listCOMP.
So here we go:

  1. Barebones/ sometimes weird api:
    1.1. The biggest problem is that you cannot directly access a cell of a listCOMP and tell it what to do. All attributes of the listCOMP are read-only and although you actually can modify them, sometimes it will lead to listcomp stop responding to any further commands.
    1.2. The hierarchy of the attributes is confusing: you have cell attributes, row attributes, col attributes, table attributes that all contribute to the final look in a very obscured way. But also as mentioned before, all these attributes are read only, so you can only query them, but in this case most of the time these attributes will give you None as an answer, despite you can clearly see that this is not None by the way your cell/row/col looks. To actually get final value of the cell you need to query it from displayAttribs property, which raises the question why do we even need cell/row/col etc attribs?
    Also if you compare memory addresses of cellAttribs of listCOMP and attribs that gets passed in onInitCell callback you will see that it’s different objects
    1.3. The only way you can alter the look of your cells is via onInitCell/row/col callback. Which happens automatically, you don’t have any control over it. It happens when new cells needs to be drawn because you are scrolling through or when you press reset (this is actually the only way you can trigger those callbacks manually), it means that every time you want to change the look of the listCOMP you need to reset the whole thing, which is an overkill in most cases.(Because I store cell attribs in my objects at the moment of cell initialization I can affect some attributes without resetting the whole thing, but some of them don’t work reliably this way).
    1.4. In general the api is very poor. For a thing that allow such deep level of customization we only have two methods: scroll and setKeyboardFocus

  2. Bugginess
    2.1 There are a lot of small bugs surrounding listCOMP . Unfortunately most of them are very random so I can’t make a proper bug report, but most prominent one is listCOMP randomly freaks out and says onInitRow was given 4 arguments when it only takes three, keep in mind that user can’t call this callback and also I don’t have any code in it so it just says return. Which means it’s some kind of behind the scenes problem
    2.2. The initialization order of cells rows columns and table is shuffled. You can simply put a print statement in each onInit callback and see it.
    2.3. I had a small problem with my code in which one cell from a column had a different colWidth compared to other ones and this was completely freaking out the listCOMP it was basically rendering all the content on top of each other. Although it was my mistake in the first place, I think listCOMP should at least issue a warning in that case or maybe automatically set the colWidth to the biggest colWidth value of the cell in a given column

  3. Lack of documentation
    3.1. I spent a whole 8 hours day looking for the first column of my content, it was gone. I checked everything only to realize in the end that the rowIndent property should be set to -1 to have no effect (why?) and I was initializing it to 0.
    3.2. There is no explanation of the idea behind different attributes of the list comp (cellAttribs, rowAttribs etc.)
    3.3. The internal mechanics are not documented, it took me a while to realize that if you reset the listCOMP all the objects that were visible are getting reused and not destroyed but as soon as the cell goes out of sight it gets quietly destroyed. It would be nice to have some degree of control over this behaviour or at least have it explicitly documented
    3.4. It also took me a while to troubleshoot onRollover with off cell callbacks on. It was never documented but I found out that in some cases it gives you -1 for row/col index and sometimes it gives you None, which was completely tripping up my callback logic and wasn’t easy to find.

  4. Lack of functionality
    To be honest listCOMP feels like it was very quickly put together from the initial python prototype and since then nobody touched it
    4.1. No way of having a padding or margin in the cells, so your text in the adjacent cells will just render next to each other without any separation
    4.2. No deeper control over the backend of listCOMP: can’t control initialization of single cells/rows/colls, only a reset that flushes everything at once.
    4.3. No row/col size auto adjustments based on the text size: you need to calculate it yourself from textsize and other parameters
    4.4. Word wrap looks ugly: it will just very mechanically put the letters that won’t fit on the next string

There’s a lot of tiny stuff that I probably forgot to mention because it wasn’t so prominent.
Also I apologize if it came out a bit angry, I didn’t have such intentions, it’s just the fact that I spent so much time wrestling with listCOMP to make it do in the end not a very complicated functionality and the amount of head scratching and wtf’s I had along the way, so it’s hard to stay away from emotions in my text :slight_smile:

Last but not least, fot it not to be just me blowing off some steam, I actually have a list of concrete suggestions on how to improve listCOMP

  1. Make a listCompCell class and hide all attribs behind its interface (it’s even weird that oninitcell gives you an instance of td.ListAttribs class and not some kind of cell object). Make this class interface directly accept cell property modifications and then you can just store it (in case this cell is currently not in sight) and apply as soon as cell.render() method is called

  2. Provide a method to connect an object to a listcomp, so that when you click on the cell for example you can directly know which object instance you are selecting, rather than deriving this information from row/col index or even from text of the selected cell.

  3. Provide a better boilerplate experience: right out of the box it’s very confusing to understand what you should do in order to make it start showing some text, whereas in excel or similar software you can straight away double click and start editing.

  4. Add niceties like being able to drag and drop out of the box or being able to resize rows and cols with mouse

  5. Improve the documentation

Thanks, I hope it helps.

Good feedback. The listCOMP is indeed very barebones, which is why I made lister to facilitate using it. The lister component does a lot of complicated stuff in Python to help fill out the minimal feature set of listCOMP. Certainly neither one is perfect and we have discussed upgrading/improving. This will further that discussion.

2 Likes

Hi Densi.

Thanks very much for your feedback. as Ivan stated listCOMP is the basis of the much more developed lister Component found in the UI section of the palette. There are known limitations, so I’ll try to go through each of your points, and see what can be further explained, documented or logged for fixing.

1.1
Do you have an example of it not responding further?
Each cell is defined by its cell, row, column and table attributes in that order. You can write them at any time.
Example:
n = op(‘list1’)
n.cellAttribs[0,0].text = ‘ABC’

There’s no need to hit reset.
onInitCell/Row/Col/Table() is just called when the cell is yet to be initialized and is being rendered.

1.2
The reason there are four sets of attributes is to efficiently set common attributes.
Example: You can set the font globally for the whole table, make only one row green and another red, and specify the text in a single cells. If more cells are added a row, they are automatically made red or green with the same font, etc.

If a cell/row/col/table attribute is set to None it means it’s not defined at that specific level.
And they are in fact all writable. (see 1.1)
Only the final combined result in displayAttribs is read-only.

‘If you compare memory addresses of cellAttribs of listCOMP and attribs that gets passed in onInitCell callback you will see that it’s different objects.’

What is the reason you are comparing the memory address though? I would not assume they should be identical. The actual objects are C++ objects, and the python object refer to them.

1.3. See above. You can directly alter the attributes at any point.
Also, I would not store those passed in arguments. Refer to them directly when you need to update them: n.cellAttrib[r,c] n.rowAttrib[r] etc.

1.4. Besides scroll and setKeyboardFocus and the direct modificaton of the row/col/cell/table attributes what functionality are you looking to use? I would strongly suggest looking at the lister in the palette which has a very well developed interace.

2.1 ‘onInitRow was given 4 arguments when it only takes three’.
That’s interesting. I haven’t come across this myself, but if you can reproduce that would go a long way to us fixing it.

2.2. Initialization order is based on different factors included whats on-screen, and what hasn’t been directly modified yet. If you need something done exactly once, you can use onInitTable().
2.3. Can you submit an example? Sounds like something we can fix.

3.1. We’ll look into documenting rowIndent better. That does sound frustrating.

3.2. Agreed, the hierarchy order needs to be explained better.

3.3. The internal mechanisms aren’t guaranteed to remain constant though, as we find more efficient ways of processing and rendering cells. Was this a result of you trying to store the callback arguments for later updating? If so, then you would need to update them directly as described above.

3.4. Agreed, the onRollover values need to be better documented when rolling into non-cell and non-panel areas.

4.1. Agreed, padding would be a great RFE. We had this in the Table COMP previously.

4.2. I think this is covered above.

4.3. Another good rfe. A couple of users have asked for this recently.

4.4. Good observation. We can review if its similar to some of our other wordwrapping strategies.

Requests:
‘listCompCell with direct attributes’ Again, I think this is described above.

‘connect object to a listcomp’
Not sure exactly how this would work. You can always use storage on a node in general, and access it with the row + column parameters from the callback no?

‘better boilerplate experience / drag drop / resize’
Have a look at the lister component in the palette. There’s lots to do there still, but I think it addresses some of the starting functionality you’re looking for.
‘Improve the documentation’

Agreed!

So thanks very much for your feedback and persistence.
Let us know if my above explanations are applicable to your experience and we can defintely work on improving documentation and missing cell text features.

Cheers.
Rob B.

Hey @rob thanks a lot for such an in-depth answer. I actually was able to make small adjustments to my design and it simplified some stuff for me. I think my main point of frustration was coming from two problems combined: cellAttribs, rowAttribs, colAttribs and tableAttribs are all marked as read only in the documentation (now that I think about, it doesn’t make their members read-only d’uh) and second thing is that because of first one I was under impression that directly writing to those members means abusing the system somehow (and I had some user errors in the process I guess which reinforced that belief) so thanks for your feedback, it clears a lot of misunderstanding on my end!

That’s great we were able to clear some things up.
But you’re absolutely right, the python documentation is misleading when it lists members as read-only vs the member’s members as writable. We’ve logged these documentation pitfalls in our database for cleanup.
Cheers.

[EDIT:]

I’ve re-ordered and added some more clear descriptions and examples:
https://docs.derivative.ca/ListCOMP_Class

1 Like