please make TableListBox::refreshComponentForRow() virtual


#1

I need to be able to replace the standard juce TableListRowComp with one of my own.

This has to do with the way that the standard one doesnt allow us to customise the appearance of the listbox for the area shown below the last ACTUAL row of data.

For example to make the background colour the same, or to make alternate lines a different colour ( as on the Mac ) .

I would like therefore to be able to override TableListBox::refreshComponentForRow() with one of my own - so I can create one of my own.

I think a new abstract class ( interface ) will needed to so my new component inherits from this abstract class interface ( the existing TableListRowComp will need to as well )

For the time being i have had to resort to basically creating a copy of the TableListbox files and modifying and renaming classes etc. But i’d prefer not to fork my
JUCE dependencies here.


#2

TableListBox inherits ListBoxModel, so that function is already virtual (it’s just not explicitly marked as such, since that isn’t strictly required). You should be able to just override it (though make sure you manually call TableListBox::refreshComponentForRow in there if you do!).

However, I’ve no idea if it will actually solve your problem, of course - I’m not sure if that function actually gets called for rows higher than getNumRows(). Also, I’ve no idea if TableListBox actually makes assumptions about the type of the component used for the rows, since it normally creates them itself.

TBH, you’re probably better off just overriding paint() and just drawing your desired background based on the current scroll position and row height.


#3

ah of course. good point. I’ll try that.

it was commented as “internal” which threw me off - thinking it must be inaccessible.


#4

nope. doesnt work. Listbox updateContents() works directly on a pointer to ListBoxRowComponent


 void updateContents()
    {
        hasUpdated = true;
        const int rowHeight = owner.getRowHeight();

        if (rowHeight > 0)
        {
            const int y = getViewPositionY();
            const int w = getViewedComponent()->getWidth();

            const int numNeeded = 2 + getMaximumVisibleHeight() / rowHeight;
            rows.removeRange (numNeeded, rows.size());

            while (numNeeded > rows.size())
            {
                ListBoxRowComponent* newRow = new ListBoxRowComponent (owner);
                rows.add (newRow);
                getViewedComponent()->addAndMakeVisible (newRow);
            }

            firstIndex = y / rowHeight;
            firstWholeIndex = (y + rowHeight - 1) / rowHeight;
            lastWholeIndex = (y + getMaximumVisibleHeight() - 1) / rowHeight;

            for (int i = 0; i < numNeeded; ++i)
            {
                const int row = i + firstIndex;
                ListBoxRowComponent* const rowComp = getComponentForRow (row);

                if (rowComp != nullptr)
                {
                    rowComp->setBounds (0, row * rowHeight, w, rowHeight);
                    
                    rowComp->update (row, owner.isRowSelected (row));
                }
            }
        }







#5

I’ve found this a lot more messy than just using inheritance, overriding and the like. In the end i’m having to take the route of making customised copies of both ListBox and TableListBox

It would be much better if the standard classes can just be tweaked a little to handle my needs.

ListBox has to be modified because of code in Listbox::ListViewport


    void updateVisibleArea (const bool makeSureItUpdatesContent)
    {
        hasUpdated = false;

        const int newX = getViewedComponent()->getX();
        int newY = getViewedComponent()->getY();
        const int newW = jmax (owner.minimumRowWidth, getMaximumVisibleWidth());
        

    
        // OLD const int newH =  owner.totalItems * owner.getRowHeight();  // D STENNING
        const int newH = getMaximumVisibleHeight();  // D STENNING
        

        if (newY + newH < getMaximumVisibleHeight() && newH > getMaximumVisibleHeight())
            newY = getMaximumVisibleHeight() - newH;

        getViewedComponent()->setBounds (newX, newY, newW, newH);

        if (makeSureItUpdatesContent && ! hasUpdated)
            updateContents();
    }

I also had to modify the TableListbox file

Put simply - the classes need to allow for all the row component instances BEYOND the actual rows in the model to be optionally handled. Whether for a mouse click or for painting the background ( or maybe even foreground )

I will submit my final classes here.

I plan to merge my versions of ListBox and TableListBox into just one class - since its getting far too complicated.

I’m doing all this to replicate the way XOJO ListBoxes work - which are always multi column and allow all the above.