mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
TreeView: Fixed a potential crash when dragging a TreeViewItem with a custom component
This commit is contained in:
parent
7b34d56069
commit
e28525b05d
2 changed files with 40 additions and 24 deletions
|
|
@ -265,7 +265,10 @@ public:
|
|||
ItemComponent* getItemComponentAt (Point<int> p)
|
||||
{
|
||||
auto iter = std::find_if (itemComponents.cbegin(), itemComponents.cend(),
|
||||
[p] (const std::unique_ptr<ItemComponent>& c) { return c->getBounds().contains (p); });
|
||||
[p] (const std::unique_ptr<ItemComponent>& c)
|
||||
{
|
||||
return c->getBounds().contains (p);
|
||||
});
|
||||
|
||||
if (iter != itemComponents.cend())
|
||||
return iter->get();
|
||||
|
|
@ -275,21 +278,35 @@ public:
|
|||
|
||||
ItemComponent* getComponentForItem (const TreeViewItem* item) const
|
||||
{
|
||||
if (item != nullptr)
|
||||
{
|
||||
auto iter = std::find_if (itemComponents.cbegin(), itemComponents.cend(),
|
||||
[item] (const std::unique_ptr<ItemComponent>& c)
|
||||
{
|
||||
return &c->getRepresentedItem() == item;
|
||||
});
|
||||
const auto iter = std::find_if (itemComponents.begin(), itemComponents.end(),
|
||||
[item] (const std::unique_ptr<ItemComponent>& c)
|
||||
{
|
||||
return &c->getRepresentedItem() == item;
|
||||
});
|
||||
|
||||
if (iter != itemComponents.cend())
|
||||
return iter->get();
|
||||
}
|
||||
if (iter != itemComponents.end())
|
||||
return iter->get();
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void itemBeingDeleted (const TreeViewItem* item)
|
||||
{
|
||||
const auto iter = std::find_if (itemComponents.begin(), itemComponents.end(),
|
||||
[item] (const std::unique_ptr<ItemComponent>& c)
|
||||
{
|
||||
return &c->getRepresentedItem() == item;
|
||||
});
|
||||
|
||||
if (iter != itemComponents.end())
|
||||
{
|
||||
if (isMouseDraggingInChildComp (*(iter->get())))
|
||||
owner.hideDragHighlight();
|
||||
|
||||
itemComponents.erase (iter);
|
||||
}
|
||||
}
|
||||
|
||||
void updateComponents()
|
||||
{
|
||||
std::vector<ItemComponent*> componentsToKeep;
|
||||
|
|
@ -324,10 +341,7 @@ public:
|
|||
}
|
||||
else
|
||||
{
|
||||
if (isMouseDraggingInChildComp (*comp))
|
||||
comp->setSize (0, 0);
|
||||
else
|
||||
itemComponents.erase (itemComponents.begin() + i);
|
||||
itemComponents.erase (itemComponents.begin() + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -445,7 +459,7 @@ private:
|
|||
void mouseMoveInternal (const MouseEvent& e) { updateItemUnderMouse (e); }
|
||||
void mouseExitInternal (const MouseEvent& e) { updateItemUnderMouse (e); }
|
||||
|
||||
bool isMouseDraggingInChildComp (const Component& comp) const
|
||||
static bool isMouseDraggingInChildComp (const Component& comp)
|
||||
{
|
||||
for (auto& ms : Desktop::getInstance().getMouseSources())
|
||||
if (ms.isDragging())
|
||||
|
|
@ -1373,6 +1387,12 @@ TreeViewItem::TreeViewItem()
|
|||
uid = nextUID++;
|
||||
}
|
||||
|
||||
TreeViewItem::~TreeViewItem()
|
||||
{
|
||||
if (ownerView != nullptr)
|
||||
ownerView->viewport->getContentComp()->itemBeingDeleted (this);
|
||||
}
|
||||
|
||||
String TreeViewItem::getUniqueName() const
|
||||
{
|
||||
return {};
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ public:
|
|||
TreeViewItem();
|
||||
|
||||
/** Destructor. */
|
||||
virtual ~TreeViewItem() = default;
|
||||
virtual ~TreeViewItem();
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the number of sub-items that have been added to this item.
|
||||
|
|
@ -313,13 +313,9 @@ public:
|
|||
callback. But if you do return a component, it will be positioned in the
|
||||
TreeView so that it can be used to represent this item.
|
||||
|
||||
The component returned will be managed by the TreeView, so always return
|
||||
a new component, and don't keep a reference to it, as the TreeView will
|
||||
delete it later when it goes off the screen or is no longer needed. Also
|
||||
bear in mind that if the component keeps a reference to the item that
|
||||
created it, that item could be deleted before the component. Its position
|
||||
and size will be completely managed by the tree, so don't attempt to move it
|
||||
around.
|
||||
The component returned will be managed by the TreeView and will be deleted
|
||||
later when it goes off the screen or is no longer needed. Its position and
|
||||
size will be completely managed by the tree, so don't attempt to move it around.
|
||||
|
||||
Something you may want to do with your component is to give it a pointer to
|
||||
the TreeView that created it. This is perfectly safe, and there's no danger
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue