void updateLocation (const bool canDoExternalDrag, const Point<int>& screenPos)
    {
        DragAndDropTarget::SourceDetails details (sourceDetails);

        setNewScreenPos (screenPos);

        Component* newTargetComp;
        DragAndDropTarget* const newTarget = findTarget (screenPos, details.localPosition, newTargetComp);

        setVisible (newTarget == nullptr || newTarget->shouldDrawDragImageWhenOver());

        if (newTargetComp != currentlyOverComp)
        {
            DragAndDropTarget* const lastTarget = getCurrentlyOver();

            if (lastTarget != nullptr && details.sourceComponent != nullptr
                  && lastTarget->isInterestedInDragSource (details))
                lastTarget->itemDragExit (details);

            currentlyOverComp = newTargetComp;

            if (newTarget != nullptr
                  && newTarget->isInterestedInDragSource (details))
                newTarget->itemDragEnter (details);
        }

        sendDragMove (details);

        if (canDoExternalDrag && getCurrentlyOver() == nullptr)
            checkForExternalDrag (details, screenPos);
    }
    void sendDragMove (DragAndDropTarget::SourceDetails& details) const
    {
        DragAndDropTarget* const target = getCurrentlyOver();

        if (target != nullptr && target->isInterestedInDragSource (details))
            target->itemDragMove (details);
    }
    ~DragImageComponent()
    {
        if (owner->dragImageComponent == this)
            owner->dragImageComponent.release();

        if (mouseDragSource != nullptr)
        {
            mouseDragSource->removeMouseListener (this);

            DragAndDropTarget* const current = getCurrentlyOver();

            if (current != nullptr && current->isInterestedInDragSource (sourceDetails))
                current->itemDragExit (sourceDetails);
        }
    }
    void updateLocation (const bool canDoExternalDrag, const Point<int>& screenPos)
    {
        // (note: use a local copy of this in case a callback runs a modal loop and deletes
        // this object before it returns)
        DragAndDropTarget::SourceDetails details (sourceDetails);

        Point<int> newPos (screenPos + imageOffset);

        if (getParentComponent() != nullptr)
            newPos = getParentComponent()->getLocalPoint (nullptr, newPos);

        //if (newX != getX() || newY != getY())
        {
            setTopLeftPosition (newPos.getX(), newPos.getY());

            Point<int> relPos;
            DragAndDropTarget* const newTarget = findTarget (screenPos, relPos);
            Component* newTargetComp = dynamic_cast <Component*> (newTarget);

            drawImage = (newTarget == nullptr) || newTarget->shouldDrawDragImageWhenOver();

            if (newTargetComp != currentlyOverComp)
            {
                DragAndDropTarget* const lastTarget = getCurrentlyOver();

                if (lastTarget != nullptr && details.sourceComponent != nullptr
                      && lastTarget->isInterestedInDragSource (details))
                    lastTarget->itemDragExit (details);

                currentlyOverComp = newTargetComp;

                if (newTarget != nullptr)
                {
                    details.localPosition = relPos;

                    if (newTarget->isInterestedInDragSource (details))
                        newTarget->itemDragEnter (details);
                }
            }

            {
                DragAndDropTarget* const target = getCurrentlyOver();
                if (target != nullptr)
                {
                    details.localPosition = relPos;

                    if (target->isInterestedInDragSource (details))
                        target->itemDragMove (details);
                }
            }

            if (getCurrentlyOver() == nullptr && canDoExternalDrag && ! hasCheckedForExternalDrag)
            {
                if (Desktop::getInstance().findComponentAt (screenPos) == nullptr)
                {
                    hasCheckedForExternalDrag = true;
                    StringArray files;
                    bool canMoveFiles = false;

                    if (owner->shouldDropFilesWhenDraggedExternally (details, files, canMoveFiles)
                         && files.size() > 0)
                    {
                        WeakReference<Component> thisWeakRef (this);
                        setVisible (false);

                        if (ModifierKeys::getCurrentModifiersRealtime().isAnyMouseButtonDown())
                            DragAndDropContainer::performExternalDragDropOfFiles (files, canMoveFiles);

                        delete thisWeakRef.get();
                        return;
                    }
                }
            }
        }
    }