Sign In/My Account | View Cart  

advertisement

AddThis Social Bookmark Button

Article:
  Working With Bitmap Images; Document-Based Application Redux
Subject:   Making the view a dragging destination
Date:   2002-04-27 17:05:11
From:   michele
Here is my implementation of drag and drop.


Making the view a dragging destination



Add the following methods to IAImageView.m:


1 - Register for dragged types when initializing the image view


- (id) initWithCoder: (NSCoder *) coder
{
if (self = [super initWithCoder: coder])
{
[self registerForDraggedTypes: [NSImage imagePasteboardTypes]];
}


return self;
}


2 - At the beginning of the dragging operation, set a flag to highlight the view if the pasteboard contains a valid image and the dragging operation is copying


Declare the flag in IAImageView.h


BOOL highlight;


Implement the method in IAImageView.m


- (NSDragOperation) draggingEntered: (id <NSDraggingInfo>) sender
{
if ([NSImage canInitWithPasteboard: [sender draggingPasteboard]] &&
[sender draggingSourceOperationMask] & NSDragOperationCopy)
{
highlight = YES;
[self setNeedsDisplay: YES];
return NSDragOperationCopy;
}


return NSDragOperationNone;
}


3 - Whenever the mouse quits the dragging destination, set a flag to unhighlight the view


- (void) draggingExited: (id <NSDraggingInfo>) sender
{
highlight = NO;
[self setNeedsDisplay: YES];
}


4 - Check if the pasteboard contains a valid image


- (BOOL) prepareForDragOperation: (id <NSDraggingInfo>) sender
{
highlight = NO;
[self setNeedsDisplay: YES];
return [NSImage canInitWithPasteboard: [sender draggingPasteboard]];
}


5 - Performs the dragging operation


- (BOOL) performDragOperation: (id <NSDraggingInfo>) sender
{
// Don't drag if the source = the destination
if ([sender draggingSource] != self)
{
NSURL *fileURL;

// Check if there is a valid image in pasteboard
if ([NSImage canInitWithPasteboard: [sender draggingPasteboard]])
{
// Insert the image into the view
[[self image] initWithPasteboard: [sender draggingPasteboard]];
// Rescale the image to the current scaling value
[self scaleFrameBy: [[[self window] delegate] getScale]];
}


// Retrieve the name of the file
fileURL = [NSURL URLFromPasteboard: [sender draggingPasteboard]];
if (fileURL != NULL)
{
// Set the window title to the name of the file
[[self window] setTitle: [fileURL absoluteString]];
}
else
{
[[self window setTitle: @"(no name)"];
}
}


return YES;
}


6 - Change the drawRect method to display a border around the dragging destination


Add the following at the end of the method


if (highlight)
{
[[NSColor grayColor] set];
[NSBezierPath setDefaultLineWidth: 5];
[NSBezierPath strokeRect: rect];
}


7 - Add a method to IAWindowController.h to get the current scale value


In IAWindowController.h


- (float) getScale;


In IAWindowController.m


- (float) getScale
{
return ([zoomControl floatValue] / 100.0);
}


8 - Add #import "IAWindowController.h" in IAImageView.m for the getScale method


Full Threads Oldest First

Showing messages 1 through 6 of 6.

  • Making the view a dragging destination
    2002-05-02 21:17:46  psheldon [View]

    Step 5 had a syntax error one of the self windows didn't have a right enclosing square bracket.

    Evidentally, not all methods need be mentioned in the header file, rather these are only used in the name space of the implementation. What are such methods called?

    When I made a new window from the file menu item, it always came in with my default gif, Yoda.gif, but I could still drag another gif onto that window and Yoda would be supplanted. Does this cause memory leak or is the old image in ram automatically released?

    You've commented not only the code but also the e mail about the code and that's good, but I am green at this stuff.

    initWithCoder evidenced itself as an override with the message to super and that fact that, though it was restricted to the name space of IAImageView.m, there was not visible call to it there.

    Help Viewer with initWithCoder asked kind of scared me, but I've faced the deamons and stared down code before.

    Registering intuits to me like something of abstract generality that those who speak this stuff know as so fundamental it probably isn't documented formally.

    There seems something that looks like type coercion of a sender which also strikes me with wonder.

    I liked the draggingEntered and draggingExited touch and it clearly illustrated distributed code in oop with drawRect.

    I also remark at all this sender machinary doesn't require wiring work, dragging is built into the frameworks, but perhaps there's a hypothetical drag event filter in the hypothetical forced typing? I'd really like to get clear what is going on with the syntax here. I don't like making too many hypotheses.

    To be contrary, I tried dragging Dennis Gabor's nobel lecture pdf to the window and got the first page complete with figure, but I didn't get the "whole picture" (35 pages).
    ;-)
    Hard to imagine something I almost understood dealing with decoding and rendering pdf's.

    When I started looking at this drag code, I really wondered if I had anything to say or anything that I understood by it. At first I felt dwarfed by this drag development, but I feel much better about it having tried to write about what I saw, not so much a dwarf.

    I hope, not to "one up", but rather to amplify people by commenting on what they say.

    There was this Chinese guy I could barely understand through the accent talking about Higgs symmetry breaking in particle physics (nobel level stuff) and only the fellow who introduced him dared to ask him a question. I feared his response to anything would be so incomprehensible I could not show thanks in my face. A dead audience can eventually wear you down, so I wrote him very politely an e mail on what I understood about what he said. He told me when I was right and gave brief provacative answers where I still am thoroughly confused, but not as much as before he answered my e mail. The e mail had no confusing accent. I did refrain from asking a followup on where I remained confused, but rather thanked him and voicemailed a local prof (the guy who introduced the speaker). I think both I and the speaker were happier for the transaction and both a bit wiser. I'm terribly sorry that all colloquia are over this semester, because follow up e mails are both not intrusive as questions at the colloquia and provide a way to study the notes merely requiring corrections from the speaker.

    • Making the view a dragging destination
      2002-05-03 12:34:15  michele [View]

      Hello p,

      "Evidentally, not all methods need be mentioned in the header file, rather these are only used in the name space of the implementation. What are such methods called? "

      They are inherited, so you don't need to put them in the header file, but you can. Do what you feel.

      "When I made a new window from the file menu item, it always came in with my default gif, Yoda.gif, but I could still drag another gif onto that window and Yoda would be supplanted. Does this cause memory leak or is the old image in ram automatically released?"

      No, it's designed so that there is no memory leak. You can test it with ObjectAlloc (in Developper Applications). Launch ObjectAlloc, put a few breaks in strategic places in your code in PB, debug compile, open your debug built in Object Alloc and watch your own classes.

      "initWithCoder evidenced itself as an override with the message to super and that fact that, though it was restricted to the name space of IAImageView.m, there was not visible call to it there. "

      If you want to see when a part of your code is called, put a descriptive NSLog message in all methods so near as the beginning of the code as you can (I mean, after the variables), say NSLog(@"Enter mymethod"); Then debug run. You'll have a trace of all calls: yours and the underlying ones.

      "To be contrary, I tried dragging Dennis Gabor's nobel lecture pdf to the window and got the first page complete with figure, but I didn't get the "whole picture" (35 pages). "

      I'm not sure, but I remember playing with Preview and Acrobat for pdfs. Try to change the application to open the pdf (either Acrobat or Preview). I know one of them gives you the whole file (just don't remember which one).

      Drag and drop is explained in Programming Topics.

      Michèle




      • is Programming Topics a pdf?
        2002-05-09 07:08:32  psheldon [View]

        Looked for it with Sherlock. There are many many pdf files. I recall something about ApKit from long ago where I started to read about model view controller but felt not wise enough to follow then. I might like to read such a text now.
      • both Acrobat and Preview show whole pdf
        2002-05-09 06:54:38  psheldon [View]

        The drag operation to your application only gets the first page into an image.
      • Making the view a dragging destination
        2002-05-05 21:49:21  dallasmac [View]


        I added the drag and drop code, but dragging an image only works after I have opened an image.

        Is there a way that the drag event work when the inital window appears.

        Thanks

        Steve
        • Making the view a dragging destination
          2002-05-06 13:19:45  michele [View]

          Basically no, because while dragging an image you put the data (raw, bitmap, etc..) in a NSImage which will be put in turn into an NSImageView.

          That's why you need an existing NSImage (even transparent one) to drag another into it. See the Composite Lab example in AppKit for more details.

          Michèle