Browse Source

TreeView: Fixed a potential crash when dragging a TreeViewItem with a custom component

v6.1.6
ed 4 years ago
parent
commit
e28525b05d
2 changed files with 41 additions and 25 deletions
  1. +37
    -17
      modules/juce_gui_basics/widgets/juce_TreeView.cpp
  2. +4
    -8
      modules/juce_gui_basics/widgets/juce_TreeView.h

+ 37
- 17
modules/juce_gui_basics/widgets/juce_TreeView.cpp View File

@@ -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;
});
if (iter != itemComponents.cend())
return iter->get();
}
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())
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 {};


+ 4
- 8
modules/juce_gui_basics/widgets/juce_TreeView.h View File

@@ -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…
Cancel
Save