NSDraggingSession distorts the images I give it


Graham Cox
 

I’m modernising some old code that does drag and drop the old, simple and perfectly functional (but deprecated) way.

The new way seems twice as complicated to me, but hey-ho.

Anyway, I’m creating NSDraggingItems for each item to be dragged, and I’m setting the image and frame to sane values. When I start to drag the items however, the images are slightly resized - they expand widthways a small amount, but vertically a somewhat larger amount, making each item appear to stretch vertically. It looks like crap.

The images are actually square - and I set the image size to match the frame size, which has the same width and height.

for( DKOLibraryItem* libItem in itemsToDrag )
{
NSDraggingItem* dragItem = [[NSDraggingItem alloc] initWithPasteboardWriter:libItem];
NSRect libItemRect = [dv imageRectForItemAtIndex:dragItemIndex]; // this rect is square, width = height


NSImage* icon = [libItem.previewImage copy];
icon.size = libItemRect.size;


[dragItem setDraggingFrame:libItemRect contents:icon];
[icon release];

//…. other stuff
}

Has anyone some clue what’s going on here?




—Graham




Jon Gotow
 

Judging from the video, your images are not square. It looks like they're only as large as they need to be to contain the drawn item, and are getting stretched to fit your square NSDraggingItem icon.

Any chance you changed the image rendering code inside of [dv imageRectForItemAtIndex:dragItemIndex] as well?

- Jon

On Nov 5, 2019, at 9:42 PM, Graham Cox <graham@mapdiva.com> wrote:

I’m modernising some old code that does drag and drop the old, simple and perfectly functional (but deprecated) way.

The new way seems twice as complicated to me, but hey-ho.

Anyway, I’m creating NSDraggingItems for each item to be dragged, and I’m setting the image and frame to sane values. When I start to drag the items however, the images are slightly resized - they expand widthways a small amount, but vertically a somewhat larger amount, making each item appear to stretch vertically. It looks like crap.

The images are actually square - and I set the image size to match the frame size, which has the same width and height.

for( DKOLibraryItem* libItem in itemsToDrag )
{
NSDraggingItem* dragItem = [[NSDraggingItem alloc] initWithPasteboardWriter:libItem];
NSRect libItemRect = [dv imageRectForItemAtIndex:dragItemIndex]; // this rect is square, width = height

NSImage* icon = [libItem.previewImage copy];
icon.size = libItemRect.size;

[dragItem setDraggingFrame:libItemRect contents:icon];
[icon release];

//…. other stuff
}

Has anyone some clue what’s going on here?

Here’s a short video showing what I’m seeing. http://s3.amazonaws.com/Mapdiva/Video/Screen%20Recording%202019-11-06%20at%203.40.09%20pm.mov



—Graham




Jon Gotow
 

Oh, my bad. I mean the drawing code within libItem.previewImage.

- Jon

On Nov 5, 2019, at 10:13 PM, Jon Gotow <gotow@stclairsoft.com> wrote:

Judging from the video, your images are not square. It looks like they're only as large as they need to be to contain the drawn item, and are getting stretched to fit your square NSDraggingItem icon.

Any chance you changed the image rendering code inside of [dv imageRectForItemAtIndex:dragItemIndex] as well?

- Jon


On Nov 5, 2019, at 9:42 PM, Graham Cox <graham@mapdiva.com> wrote:

I’m modernising some old code that does drag and drop the old, simple and perfectly functional (but deprecated) way.

The new way seems twice as complicated to me, but hey-ho.

Anyway, I’m creating NSDraggingItems for each item to be dragged, and I’m setting the image and frame to sane values. When I start to drag the items however, the images are slightly resized - they expand widthways a small amount, but vertically a somewhat larger amount, making each item appear to stretch vertically. It looks like crap.

The images are actually square - and I set the image size to match the frame size, which has the same width and height.

for( DKOLibraryItem* libItem in itemsToDrag )
{
NSDraggingItem* dragItem = [[NSDraggingItem alloc] initWithPasteboardWriter:libItem];
NSRect libItemRect = [dv imageRectForItemAtIndex:dragItemIndex]; // this rect is square, width = height

NSImage* icon = [libItem.previewImage copy];
icon.size = libItemRect.size;

[dragItem setDraggingFrame:libItemRect contents:icon];
[icon release];

//…. other stuff
}

Has anyone some clue what’s going on here?

Here’s a short video showing what I’m seeing. http://s3.amazonaws.com/Mapdiva/Video/Screen%20Recording%202019-11-06%20at%203.40.09%20pm.mov



—Graham




-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.


Graham Cox
 

Hi Jon,

The images are square - the rect returned by -imageRectForItemAtIndex is used to render them in the view as well as supplying the frame to the NSDraggingItem. That’s why it seems odd to me that the drag changes it.

The original image is actually a PDF Representation with a size of 93, 93. The image frame for drawing (and dragging) is 76, 76. This size depends on the ‘icon size’ the user chooses for that interface - small, medium or large. 76 is the medium size. While the images themselves may not always look square, whatever is rendered has a media box that is square, and the icon is rendered centred in that square, scaled to the longer side. What that means is that no matter what overall shape the image is, the icon that results is square - it just contains some extra transparent background if needed.

In any case, the same rect is always used for rendering the image in the view and for the dragging frame. So even if it wasn’t square, they should agree.

—Graham

On 6 Nov 2019, at 4:13 pm, Jon Gotow <gotow@stclairsoft.com> wrote:

Judging from the video, your images are not square. It looks like they're only as large as they need to be to contain the drawn item, and are getting stretched to fit your square NSDraggingItem icon.

Any chance you changed the image rendering code inside of [dv imageRectForItemAtIndex:dragItemIndex] as well?

- Jon


On Nov 5, 2019, at 9:42 PM, Graham Cox <graham@mapdiva.com> wrote:

I’m modernising some old code that does drag and drop the old, simple and perfectly functional (but deprecated) way.

The new way seems twice as complicated to me, but hey-ho.

Anyway, I’m creating NSDraggingItems for each item to be dragged, and I’m setting the image and frame to sane values. When I start to drag the items however, the images are slightly resized - they expand widthways a small amount, but vertically a somewhat larger amount, making each item appear to stretch vertically. It looks like crap.

The images are actually square - and I set the image size to match the frame size, which has the same width and height.


Jon Gotow
 

I’m just relating what I’m observing in the video. Each icon is getting stretched vertically not by a uniform factor, but so that the drawn elements exactly fit the given bounds. Honestly, it looks like NSImage is ignoring the pdf media box and setting its size based on the drawn content.

Humor me here for a minute: What happens if one of the icons is a square? It’s a simple test, anyway.
Sent from my iPhone

On Nov 5, 2019, at 11:27 PM, Graham Cox <graham@mapdiva.com> wrote:

Hi Jon,

The images are square - the rect returned by -imageRectForItemAtIndex is used to render them in the view as well as supplying the frame to the NSDraggingItem. That’s why it seems odd to me that the drag changes it.

The original image is actually a PDF Representation with a size of 93, 93. The image frame for drawing (and dragging) is 76, 76. This size depends on the ‘icon size’ the user chooses for that interface - small, medium or large. 76 is the medium size. While the images themselves may not always look square, whatever is rendered has a media box that is square, and the icon is rendered centred in that square, scaled to the longer side. What that means is that no matter what overall shape the image is, the icon that results is square - it just contains some extra transparent background if needed.

In any case, the same rect is always used for rendering the image in the view and for the dragging frame. So even if it wasn’t square, they should agree.

—Graham



On 6 Nov 2019, at 4:13 pm, Jon Gotow <gotow@stclairsoft.com> wrote:

Judging from the video, your images are not square. It looks like they're only as large as they need to be to contain the drawn item, and are getting stretched to fit your square NSDraggingItem icon.

Any chance you changed the image rendering code inside of [dv imageRectForItemAtIndex:dragItemIndex] as well?

- Jon


On Nov 5, 2019, at 9:42 PM, Graham Cox <graham@mapdiva.com> wrote:

I’m modernising some old code that does drag and drop the old, simple and perfectly functional (but deprecated) way.

The new way seems twice as complicated to me, but hey-ho.

Anyway, I’m creating NSDraggingItems for each item to be dragged, and I’m setting the image and frame to sane values. When I start to drag the items however, the images are slightly resized - they expand widthways a small amount, but vertically a somewhat larger amount, making each item appear to stretch vertically. It looks like crap.

The images are actually square - and I set the image size to match the frame size, which has the same width and height.



Graham Cox
 

Hi Jon,

Turns out you’re right - the images were NOT square - they vary. It just so happened that the first image in my selection was square, and that’s what I observed in the debugger. Since it was in line with my expectations, it seemed to make sense. But actually later the images are rendered INTO a square, with the rectangle scaled to fit.

Anyway, NOT forcing them to be square, but instead doing the same “fit” calculation to arrive at a dragging frame solves the problem.

So thanks for getting me to examine my assumptions here - it was on the right track.

—Graham

On 6 Nov 2019, at 6:47 pm, Jon Gotow <gotow@stclairsoft.com> wrote:

I’m just relating what I’m observing in the video. Each icon is getting stretched vertically not by a uniform factor, but so that the drawn elements exactly fit the given bounds. Honestly, it looks like NSImage is ignoring the pdf media box and setting its size based on the drawn content.

Humor me here for a minute: What happens if one of the icons is a square? It’s a simple test, anyway.
Sent from my iPhone
On Nov 5, 2019, at 11:27 PM, Graham Cox <graham@mapdiva.com> wrote:

Hi Jon,

The images are square - the rect returned by -imageRectForItemAtIndex is used to render them in the view as well as supplying the frame to the NSDraggingItem. That’s why it seems odd to me that the drag changes it.

The original image is actually a PDF Representation with a size of 93, 93. The image frame for drawing (and dragging) is 76, 76. This size depends on the ‘icon size’ the user chooses for that interface - small, medium or large. 76 is the medium size. While the images themselves may not always look square, whatever is rendered has a media box that is square, and the icon is rendered centred in that square, scaled to the longer side. What that means is that no matter what overall shape the image is, the icon that results is square - it just contains some extra transparent background if needed.

In any case, the same rect is always used for rendering the image in the view and for the dragging frame. So even if it wasn’t square, they should agree.

—Graham



On 6 Nov 2019, at 4:13 pm, Jon Gotow <gotow@stclairsoft.com> wrote:

Judging from the video, your images are not square. It looks like they're only as large as they need to be to contain the drawn item, and are getting stretched to fit your square NSDraggingItem icon.

Any chance you changed the image rendering code inside of [dv imageRectForItemAtIndex:dragItemIndex] as well?

- Jon


On Nov 5, 2019, at 9:42 PM, Graham Cox <graham@mapdiva.com> wrote:

I’m modernising some old code that does drag and drop the old, simple and perfectly functional (but deprecated) way.

The new way seems twice as complicated to me, but hey-ho.

Anyway, I’m creating NSDraggingItems for each item to be dragged, and I’m setting the image and frame to sane values. When I start to drag the items however, the images are slightly resized - they expand widthways a small amount, but vertically a somewhat larger amount, making each item appear to stretch vertically. It looks like crap.

The images are actually square - and I set the image size to match the frame size, which has the same width and height.





Jon Gotow
 

On Nov 6, 2019, at 2:42 AM, Graham Cox <graham@mapdiva.com> wrote:

Turns out you’re right - the images were NOT square - they vary. It just so happened that the first image in my selection was square, and that’s what I observed in the debugger. Since it was in line with my expectations, it seemed to make sense. But actually later the images are rendered INTO a square, with the rectangle scaled to fit.

Anyway, NOT forcing them to be square, but instead doing the same “fit” calculation to arrive at a dragging frame solves the problem.

So thanks for getting me to examine my assumptions here - it was on the right track.
I'm glad I could help. It's just one of those things I've run into myself a million times - I _think_ I've checked all my assumptions when I'm debugging something, and end up off in the weeds (for hours or more, sometimes) because one of my basic assumptions was wrong. Fortunately, you posted that screen recording showing the behavior so I could pause it and see what the exact scaling was. Nothing like having plenty of data to look at - that makes it easy to help solve the problem.

Good luck with your app!

- Jon