Whats going on in the treeview


#1

It’s crashing for me. I have a bunch of items in the tree, and an item losing focus can cause the tree to get updated.

So if you click on item B, the item A which is losing focus says, hey, update the tree!

But in the treeview on line:172

if ((itemsToKeep[i] || (comp == Component::getComponentUnderMouse() && comp->isMouseButtonDown())) && isParentOf (comp)) { const TreeViewItem* const item = (TreeViewItem*) rowComponentItems.getUnchecked(i);

Item B says, hey I’m under the mouse and the button is down, keep me! But he’s already been deleted.

[color=red][size=200]BOOM![/size][/color]

item is a bad pointer and everything crashes.

What is the correct way to handle this?


#2

Hmm. Interesting one. In fact, the reason that the isParent() call is made is to check if the item has been moved or deleted. But it looks like things are getting called in the wrong order. How about just a quick rearrangement of the line:

if (isParentOf (comp) && (itemsToKeep[i] || (comp == Component::getComponentUnderMouse() && comp->isMouseButtonDown())))


#3

That doesn’t fix it. It crashes on the next line, not the if statement.

The problem appears to be the row component still exists, but the TreeViewItem for it has already been deleted.


#4

Ah. I see. Ok, well how about this. If the item has been deleted but is still being dragged, this should set its size to (0, 0) so that it can still receive mouse drags, but is invisible.

[code] if ((itemsToKeep[i] || (comp == Component::getComponentUnderMouse() && comp->isMouseButtonDown()))
&& isParentOf (comp))
{
if (itemsToKeep[i])
{
const TreeViewItem* const item = (TreeViewItem*) rowComponentItems.getUnchecked(i);

                Rectangle pos (item->getPositionWithinTreeView());
                pos.translate (-xAdjust, -yAdjust);
                pos.setSize (pos.getWidth() + xAdjust, item->itemHeight);

                if (pos.getBottom() >= visibleTop && pos.getY() < visibleBottom)
                {
                    keep = true;
                    comp->setBounds (pos);
                }
            }
            else
            {
                comp->setSize (0, 0);
            }
        }[/code]

#5

That fixed it, thanks.


#6