Mac应用程序 - 将文件拖放到菜单栏应用程序中

时间:2012-07-08 12:27:09

标签: objective-c xcode cocoa drag-and-drop nsstatusitem

我对这个项目的灵感来自Droplr和CloudApp mac菜单栏应用程序。我一直在尝试实现解释here的代码。

然而,当我实现代码时,菜单栏图像消失了。这是我创建状态项的代码:

- (id)init {
self = [super init];
if (self != nil) {
  // Install status item into the menu bar
  NSStatusItem *statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:STATUS_ITEM_VIEW_WIDTH];
  _statusItemView = [[StatusItemView alloc] initWithStatusItem:statusItem];
  _statusItemView.image = [NSImage imageNamed:@"Status"];
  _statusItemView.alternateImage = [NSImage imageNamed:@"StatusHighlighted"];
  _statusItemView.action = @selector(togglePanel:);
  StatusItemView* dragView = [[StatusItemView alloc] initWithFrame:NSMakeRect(0, 0, 24, 24)];
  [statusItem setView:dragView];
  [dragView release];
}
return self;
}

这是我的观点文件:

#import "StatusItemView.h"
@implementation StatusItemView
@synthesize statusItem = _statusItem;
@synthesize image = _image;
@synthesize alternateImage = _alternateImage;
@synthesize isHighlighted = _isHighlighted;
@synthesize action = _action;
@synthesize target = _target;
#pragma mark -
- (id)initWithStatusItem:(NSStatusItem *)statusItem {
  CGFloat itemWidth = [statusItem length];
  CGFloat itemHeight = [[NSStatusBar systemStatusBar] thickness];
  NSRect itemRect = NSMakeRect(0.0, 0.0, itemWidth, itemHeight);
  self = [super initWithFrame:itemRect];
  if (self != nil) {
    _statusItem = statusItem;
    _statusItem.view = self;
  }
return self;
}

#pragma mark -
- (id)initWithFrame:(NSRect)frame {
  self = [super initWithFrame:frame];
  if (self) {
    //register for drags
    [self registerForDraggedTypes:[NSArray arrayWithObjects: NSFilenamesPboardType, nil]];
  }
  return self;
}
//we want to copy the files
- (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)sender {
  return NSDragOperationCopy;
}

perform the drag and log the files that are dropped
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender {
  NSPasteboard *pboard;
  NSDragOperation sourceDragMask;
  sourceDragMask = [sender draggingSourceOperationMask];
  pboard = [sender draggingPasteboard];
  if( [[pboard types] containsObject:NSFilenamesPboardType] ) {
    NSArray *files = [pboard propertyListForType:NSFilenamesPboardType];
    NSLog(@"Files: %@",files);
  }
  return YES;
}

#pragma mark -

- (void)drawRect:(NSRect)dirtyRect {
  [self.statusItem drawStatusBarBackgroundInRect:dirtyRect withHighlight:self.isHighlighted];
  NSImage *icon = self.isHighlighted ? self.alternateImage : self.image;
  NSSize iconSize = [icon size];
  NSRect bounds = self.bounds;
  CGFloat iconX = roundf((NSWidth(bounds) - iconSize.width) / 2);
  CGFloat iconY = roundf((NSHeight(bounds) - iconSize.height) / 2);
  NSPoint iconPoint = NSMakePoint(iconX, iconY);
  [icon compositeToPoint:iconPoint operation:NSCompositeSourceOver];
}

#pragma mark -
#pragma mark Mouse tracking

- (void)mouseDown:(NSEvent *)theEvent {
  [NSApp sendAction:self.action to:self.target from:self];
}

#pragma mark -
#pragma mark Accessors
- (void)setHighlighted:(BOOL)newFlag {
  if (_isHighlighted == newFlag) return;
  _isHighlighted = newFlag;
  [self setNeedsDisplay:YES];
}

#pragma mark -
- (void)setImage:(NSImage *)newImage {
  if (_image != newImage) {
    _image = newImage;
    [self setNeedsDisplay:YES];
  }
}

- (void)setAlternateImage:(NSImage *)newImage {
  if (_alternateImage != newImage) {
    _alternateImage = newImage;
    if (self.isHighlighted) {
      [self setNeedsDisplay:YES];
    }
  }
}

#pragma mark -
- (NSRect)globalRect {
  NSRect frame = [self frame];
  frame.origin = [self.window convertBaseToScreen:frame.origin];
  return frame;
}

@end

谢谢大家!

1 个答案:

答案 0 :(得分:0)

我知道这是一个老问题,但也许这可能会有所帮助:

尝试将NSStatusItem *statusItem设置为班级的@propery。如果您有ARC,则在init函数完成后,菜单栏可能会被销毁。