mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
DragAndDropContainer: Allow custom scaling
This commit is contained in:
parent
6468088100
commit
34fdea0708
9 changed files with 195 additions and 72 deletions
|
|
@ -35,14 +35,15 @@ class DragAndDropContainer::DragImageComponent : public Component,
|
|||
private Timer
|
||||
{
|
||||
public:
|
||||
DragImageComponent (const Image& im,
|
||||
DragImageComponent (const ScaledImage& im,
|
||||
const var& desc,
|
||||
Component* const sourceComponent,
|
||||
const MouseInputSource* draggingSource,
|
||||
DragAndDropContainer& ddc,
|
||||
Point<int> offset)
|
||||
: sourceDetails (desc, sourceComponent, Point<int>()),
|
||||
image (im), owner (ddc),
|
||||
image (im),
|
||||
owner (ddc),
|
||||
mouseDragSource (draggingSource->getComponentUnderMouse()),
|
||||
imageOffset (transformOffsetCoordinates (sourceComponent, offset)),
|
||||
originalInputSourceIndex (draggingSource->getIndex()),
|
||||
|
|
@ -83,7 +84,7 @@ public:
|
|||
g.fillAll (Colours::white);
|
||||
|
||||
g.setOpacity (1.0f);
|
||||
g.drawImageAt (image, 0, 0);
|
||||
g.drawImage (image.getImage(), getLocalBounds().toFloat());
|
||||
}
|
||||
|
||||
void mouseUp (const MouseEvent& e) override
|
||||
|
|
@ -164,7 +165,7 @@ public:
|
|||
forceMouseCursorUpdate();
|
||||
}
|
||||
|
||||
void updateImage (const Image& newImage)
|
||||
void updateImage (const ScaledImage& newImage)
|
||||
{
|
||||
image = newImage;
|
||||
updateSize();
|
||||
|
|
@ -218,7 +219,7 @@ public:
|
|||
DragAndDropTarget::SourceDetails sourceDetails;
|
||||
|
||||
private:
|
||||
Image image;
|
||||
ScaledImage image;
|
||||
DragAndDropContainer& owner;
|
||||
WeakReference<Component> mouseDragSource, currentlyOverComp;
|
||||
const Point<int> imageOffset;
|
||||
|
|
@ -229,7 +230,8 @@ private:
|
|||
|
||||
void updateSize()
|
||||
{
|
||||
setSize (image.getWidth(), image.getHeight());
|
||||
const auto bounds = image.getScaledBounds().toNearestInt();
|
||||
setSize (bounds.getWidth(), bounds.getHeight());
|
||||
}
|
||||
|
||||
void forceMouseCursorUpdate()
|
||||
|
|
@ -388,17 +390,13 @@ private:
|
|||
|
||||
|
||||
//==============================================================================
|
||||
DragAndDropContainer::DragAndDropContainer()
|
||||
{
|
||||
}
|
||||
DragAndDropContainer::DragAndDropContainer() = default;
|
||||
|
||||
DragAndDropContainer::~DragAndDropContainer()
|
||||
{
|
||||
}
|
||||
DragAndDropContainer::~DragAndDropContainer() = default;
|
||||
|
||||
void DragAndDropContainer::startDragging (const var& sourceDescription,
|
||||
Component* sourceComponent,
|
||||
Image dragImage,
|
||||
const ScaledImage& dragImage,
|
||||
const bool allowDraggingToExternalWindows,
|
||||
const Point<int>* imageOffsetFromMouse,
|
||||
const MouseInputSource* inputSourceCausingDrag)
|
||||
|
|
@ -414,55 +412,53 @@ void DragAndDropContainer::startDragging (const var& sourceDescription,
|
|||
return;
|
||||
}
|
||||
|
||||
auto lastMouseDown = draggingSource->getLastMouseDownPosition().roundToInt();
|
||||
Point<int> imageOffset;
|
||||
const auto lastMouseDown = draggingSource->getLastMouseDownPosition().roundToInt();
|
||||
|
||||
if (dragImage.isNull())
|
||||
struct ImageAndOffset
|
||||
{
|
||||
dragImage = sourceComponent->createComponentSnapshot (sourceComponent->getLocalBounds())
|
||||
.convertedToFormat (Image::ARGB);
|
||||
ScaledImage image;
|
||||
Point<double> offset;
|
||||
};
|
||||
|
||||
dragImage.multiplyAllAlphas (0.6f);
|
||||
|
||||
auto lo = 150;
|
||||
auto hi = 400;
|
||||
|
||||
auto relPos = sourceComponent->getLocalPoint (nullptr, lastMouseDown);
|
||||
auto clipped = dragImage.getBounds().getConstrainedPoint (relPos);
|
||||
Random random;
|
||||
|
||||
for (auto y = dragImage.getHeight(); --y >= 0;)
|
||||
{
|
||||
auto dy = (y - clipped.getY()) * (y - clipped.getY());
|
||||
|
||||
for (auto x = dragImage.getWidth(); --x >= 0;)
|
||||
{
|
||||
auto dx = x - clipped.getX();
|
||||
auto distance = roundToInt (std::sqrt (dx * dx + dy));
|
||||
|
||||
if (distance > lo)
|
||||
{
|
||||
auto alpha = (distance > hi) ? 0
|
||||
: (float) (hi - distance) / (float) (hi - lo)
|
||||
+ random.nextFloat() * 0.008f;
|
||||
|
||||
dragImage.multiplyAlphaAt (x, y, alpha);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
imageOffset = clipped;
|
||||
}
|
||||
else
|
||||
const auto imageToUse = [&]() -> ImageAndOffset
|
||||
{
|
||||
if (imageOffsetFromMouse == nullptr)
|
||||
imageOffset = dragImage.getBounds().getCentre();
|
||||
else
|
||||
imageOffset = dragImage.getBounds().getConstrainedPoint (-*imageOffsetFromMouse);
|
||||
}
|
||||
if (! dragImage.getImage().isNull())
|
||||
return { dragImage, imageOffsetFromMouse != nullptr ? dragImage.getScaledBounds().getConstrainedPoint (-imageOffsetFromMouse->toDouble())
|
||||
: dragImage.getScaledBounds().getCentre() };
|
||||
|
||||
auto* dragImageComponent = dragImageComponents.add (new DragImageComponent (dragImage, sourceDescription, sourceComponent,
|
||||
draggingSource, *this, imageOffset));
|
||||
const auto scaleFactor = 2.0;
|
||||
auto image = sourceComponent->createComponentSnapshot (sourceComponent->getLocalBounds(), true, (float) scaleFactor)
|
||||
.convertedToFormat (Image::ARGB);
|
||||
image.multiplyAllAlphas (0.6f);
|
||||
|
||||
const auto relPos = sourceComponent->getLocalPoint (nullptr, lastMouseDown).toDouble();
|
||||
const auto clipped = (image.getBounds().toDouble() / scaleFactor).getConstrainedPoint (relPos);
|
||||
|
||||
Image fade (Image::SingleChannel, image.getWidth(), image.getHeight(), true);
|
||||
Graphics fadeContext (fade);
|
||||
|
||||
ColourGradient gradient;
|
||||
gradient.isRadial = true;
|
||||
gradient.point1 = clipped.toFloat() * scaleFactor;
|
||||
gradient.point2 = gradient.point1 + Point<float> (0.0f, scaleFactor * 400.0f);
|
||||
gradient.addColour (0.0, Colours::white);
|
||||
gradient.addColour (0.375, Colours::white);
|
||||
gradient.addColour (1.0, Colours::transparentWhite);
|
||||
|
||||
fadeContext.setGradientFill (gradient);
|
||||
fadeContext.fillAll();
|
||||
|
||||
Image composite (Image::ARGB, image.getWidth(), image.getHeight(), true);
|
||||
Graphics compositeContext (composite);
|
||||
|
||||
compositeContext.reduceClipRegion (fade, {});
|
||||
compositeContext.drawImageAt (image, 0, 0);
|
||||
|
||||
return { ScaledImage (composite, scaleFactor), clipped };
|
||||
}();
|
||||
|
||||
auto* dragImageComponent = dragImageComponents.add (new DragImageComponent (imageToUse.image, sourceDescription, sourceComponent,
|
||||
draggingSource, *this, imageToUse.offset.roundToInt()));
|
||||
|
||||
if (allowDraggingToExternalWindows)
|
||||
{
|
||||
|
|
@ -527,7 +523,7 @@ var DragAndDropContainer::getDragDescriptionForIndex (int index) const
|
|||
return dragImageComponents.getUnchecked (index)->sourceDetails.description;
|
||||
}
|
||||
|
||||
void DragAndDropContainer::setCurrentDragImage (const Image& newImage)
|
||||
void DragAndDropContainer::setCurrentDragImage (const ScaledImage& newImage)
|
||||
{
|
||||
// If you are performing drag and drop in a multi-touch environment then
|
||||
// you should use the setDragImageForIndex() method instead!
|
||||
|
|
@ -536,7 +532,7 @@ void DragAndDropContainer::setCurrentDragImage (const Image& newImage)
|
|||
dragImageComponents[0]->updateImage (newImage);
|
||||
}
|
||||
|
||||
void DragAndDropContainer::setDragImageForIndex (int index, const Image& newImage)
|
||||
void DragAndDropContainer::setDragImageForIndex (int index, const ScaledImage& newImage)
|
||||
{
|
||||
if (isPositiveAndBelow (index, dragImageComponents.size()))
|
||||
dragImageComponents.getUnchecked (index)->updateImage (newImage);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue