Browse Source

TreeView: Prevent dragging items from scrolling viewport on mobile and fix issue with dragged item component being deleted during drag operations

v6.1.6
ed 4 years ago
parent
commit
de375ab6d7
1 changed files with 63 additions and 36 deletions
  1. +63
    -36
      modules/juce_gui_basics/widgets/juce_TreeView.cpp

+ 63
- 36
modules/juce_gui_basics/widgets/juce_TreeView.cpp View File

@@ -67,8 +67,16 @@ public:
}
}
void setMouseIsOverButton (bool isOver) { mouseIsOverButton = isOver; }
TreeViewItem& getRepresentedItem() const noexcept { return item; }
void setMouseIsOverButton (bool isOver)
{
mouseIsOverButton = isOver;
repaint();
}
TreeViewItem& getRepresentedItem() const noexcept
{
return item;
}
private:
//==============================================================================
@@ -314,13 +322,13 @@ public:
void updateComponents()
{
std::vector<ItemComponent*> componentsToKeep;
std::set<ItemComponent*> componentsToKeep;
for (auto* treeItem : getAllVisibleItems())
{
if (auto* itemComp = getComponentForItem (treeItem))
{
componentsToKeep.push_back (itemComp);
componentsToKeep.insert (itemComp);
}
else
{
@@ -328,30 +336,48 @@ public:
addAndMakeVisible (*newComp);
newComp->addMouseListener (this, false);
componentsToKeep.push_back (newComp.get());
componentsToKeep.insert (newComp.get());
itemComponents.push_back (std::move (newComp));
}
}
for (int i = (int) itemComponents.size(); --i >= 0;)
{
auto& comp = itemComponents[(size_t) i];
if (scopedScrollDisabler.item != nullptr)
componentsToKeep.insert (scopedScrollDisabler.item);
if (std::find (componentsToKeep.cbegin(), componentsToKeep.cend(), comp.get())
!= componentsToKeep.cend())
{
auto& treeItem = comp->getRepresentedItem();
comp->setBounds ({ 0, treeItem.y, getWidth(), treeItem.itemHeight });
}
else
{
itemComponents.erase (itemComponents.begin() + i);
}
const auto iter = std::remove_if (itemComponents.begin(), itemComponents.end(),
[&] (auto& item) { return componentsToKeep.find (item.get()) == componentsToKeep.end(); });
itemComponents.erase (iter, itemComponents.end());
for (auto& comp : itemComponents)
{
auto& treeItem = comp->getRepresentedItem();
comp->setBounds ({ 0, treeItem.y, getWidth(), treeItem.itemHeight });
}
}
private:
//==============================================================================
struct ScopedDisableViewportScroll
{
ScopedDisableViewportScroll() = default;
explicit ScopedDisableViewportScroll (ItemComponent& c)
: item (&c)
{
item->setViewportIgnoreDragFlag (true);
}
~ScopedDisableViewportScroll()
{
if (item != nullptr)
item->setViewportIgnoreDragFlag (false);
}
SafePointer<ItemComponent> item;
};
//==============================================================================
std::unique_ptr<AccessibilityHandler> createAccessibilityHandler() override
{
@@ -363,6 +389,7 @@ private:
updateItemUnderMouse (e);
isDragging = false;
scopedScrollDisabler = {};
needSelectionOnMouseUp = false;
if (! isEnabled())
@@ -453,6 +480,8 @@ private:
auto imageOffset = pos.getPosition() - e.getPosition();
dragContainer->startDragging (dragDescription, &owner, dragImage, true, &imageOffset, &e.source);
scopedScrollDisabler = ScopedDisableViewportScroll { *itemComponent };
}
else
{
@@ -481,37 +510,34 @@ private:
void updateItemUnderMouse (const MouseEvent& e)
{
ItemComponent* newItem = nullptr;
if (! owner.openCloseButtonsVisible)
return;
if (owner.openCloseButtonsVisible)
auto* newItem = [this, &e]() -> ItemComponent*
{
if (auto* itemComponent = getItemComponentAt (e.getPosition()))
{
auto& item = itemComponent->getRepresentedItem();
auto pos = item.getItemPosition (false);
if (e.x < pos.getX()
&& e.x >= pos.getX() - owner.getIndentSize()
&& item.mightContainSubItems())
if (item.mightContainSubItems())
{
newItem = itemComponent;
const auto xPos = item.getItemPosition (false).getX();
if (xPos - owner.getIndentSize() <= e.x && e.x < xPos)
return itemComponent;
}
}
}
return nullptr;
}();
if (itemUnderMouse != newItem)
{
auto updateItem = [] (ItemComponent* itemComp, bool isMouseOverButton)
{
if (itemComp != nullptr)
{
itemComp->setMouseIsOverButton (isMouseOverButton);
itemComp->repaint();
}
};
if (itemUnderMouse != nullptr)
itemUnderMouse->setMouseIsOverButton (false);
updateItem (itemUnderMouse, false);
updateItem (newItem, true);
if (newItem != nullptr)
newItem->setMouseIsOverButton (true);
itemUnderMouse = newItem;
}
@@ -625,6 +651,7 @@ private:
std::vector<std::unique_ptr<ItemComponent>> itemComponents;
ItemComponent* itemUnderMouse = nullptr;
ScopedDisableViewportScroll scopedScrollDisabler;
bool isDragging = false, needSelectionOnMouseUp = false;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ContentComponent)


Loading…
Cancel
Save