1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file. 4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#import "ui/app_list/cocoa/item_drag_controller.h" 6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/logging.h" 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#import "ui/app_list/cocoa/apps_grid_view_item.h" 9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/base/cocoa/window_size_constants.h" 10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Scale to transform the grid cell when a drag starts. Note that 1.5 ensures 12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// that integers are used for the layer bounds when the grid cell dimensions 13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// are even. 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const CGFloat kDraggingIconScale = 1.5; 15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const NSTimeInterval kAnimationDuration = 0.2; 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)@interface ItemDragController () 20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)- (void)animateTransformFrom:(CATransform3D)fromValue 22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) useDelegate:(BOOL)useDelegate; 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)- (void)clearAnimations; 25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)@end 27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)@implementation ItemDragController 29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)- (id)initWithGridCellSize:(NSSize)size { 31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if ((self = [super init])) { 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) NSRect frameRect = NSMakeRect(0, 33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 0, 34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) size.width * kDraggingIconScale, 35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) size.height * kDraggingIconScale); 36eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::scoped_nsobject<NSView> dragView( 37eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch [[NSView alloc] initWithFrame:frameRect]); 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) [dragView setWantsLayer:YES]; 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) [dragView setHidden:YES]; 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dragLayer_.reset([[CALayer layer] retain]); 42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) [dragLayer_ setFrame:NSRectToCGRect(frameRect)]; 43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) [[dragView layer] addSublayer:dragLayer_]; 44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) [self setView:dragView]; 46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return self; 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)- (void)initiate:(AppsGridViewItem*)item 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) mouseDownLocation:(NSPoint)mouseDownLocation 52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) currentLocation:(NSPoint)currentLocation 53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) timestamp:(NSTimeInterval)eventTimestamp { 54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) [self clearAnimations]; 55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) NSView* itemView = [item view]; 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) NSPoint pointInGridCell = [itemView convertPoint:mouseDownLocation 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) fromView:nil]; 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) mouseOffset_ = NSMakePoint(pointInGridCell.x - NSMidX([itemView bounds]), 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) NSMidY([itemView bounds]) - pointInGridCell.y); 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch NSBitmapImageRep* imageRep = [item dragRepresentationForRestore:NO]; 62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) [dragLayer_ setContents:reinterpret_cast<id>([imageRep CGImage])]; 63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) [dragLayer_ setTransform:CATransform3DIdentity]; 64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Add a grow animation to the layer. 66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CATransform3D growFrom = CATransform3DScale(CATransform3DIdentity, 67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1.0 / kDraggingIconScale, 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1.0 / kDraggingIconScale, 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1.0); 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) [self animateTransformFrom:growFrom 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) useDelegate:NO]; 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) growStart_ = eventTimestamp; 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) [[self view] setHidden:NO]; 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)- (void)update:(NSPoint)currentLocation 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) timestamp:(NSTimeInterval)eventTimestamp { 79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) NSPoint pointInSuperview = [[[self view] superview] 80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) convertPoint:currentLocation 81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) fromView:nil]; 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) NSRect rect = [[self view] bounds]; 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) NSPoint anchor = NSMakePoint(NSMidX(rect), NSMidY(rect)); 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // If the grow animation is still in progress, make the point of the image 86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // that was clicked appear stuck to the mouse cursor. 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CGFloat progress = (eventTimestamp - growStart_) / kAnimationDuration; 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CGFloat currentIconScale = progress < 1.0 ? 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1.0 + (kDraggingIconScale - 1.0) * progress : 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) kDraggingIconScale; 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) pointInSuperview.x -= (mouseOffset_.x * currentIconScale + anchor.x); 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) pointInSuperview.y -= (mouseOffset_.y * currentIconScale + anchor.y); 94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) [[self view] setFrameOrigin:pointInSuperview]; 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)- (void)complete:(AppsGridViewItem*)item 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) targetOrigin:(NSPoint)targetOrigin { 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) [self clearAnimations]; 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) NSView* itemView = [item view]; 1027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch NSBitmapImageRep* imageRep = [item dragRepresentationForRestore:YES]; 103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) [dragLayer_ setContents:reinterpret_cast<id>([imageRep CGImage])]; 105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) [dragLayer_ setTransform:CATransform3DScale(CATransform3DIdentity, 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1.0 / kDraggingIconScale, 107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1.0 / kDraggingIconScale, 108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1.0)]; 109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Retain the button so it can be unhidden when the animation completes. Note 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // that the |item| and corresponding button can differ from the |item| passed 112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // to initiate(), if it moved to a new page during the drag. At this point the 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // destination page is known, so retain the button. 1147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch buttonToRestore_.reset([[item button] retain]); 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Add the shrink animation for the layer. 117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) [self animateTransformFrom:CATransform3DIdentity 118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) useDelegate:YES]; 119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) shrinking_ = YES; 120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Also animate the translation, on the view. 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // TODO(tapted): This should be merged into the scale transform, instead of 123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // using a separate NSViewAnimation. 124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) NSRect startRect = [[self view] frame]; 125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The final position needs to be adjusted since it shrinks from each side. 127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) NSRect targetRect = NSMakeRect( 128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) targetOrigin.x - NSMidX([itemView bounds]) * (kDraggingIconScale - 1), 129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) targetOrigin.y - NSMidY([itemView bounds]) * (kDraggingIconScale - 1), 130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) startRect.size.width, 131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) startRect.size.height); 132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) NSDictionary* animationDict = @{ 134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) NSViewAnimationTargetKey: [self view], 135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) NSViewAnimationStartFrameKey: [NSValue valueWithRect:startRect], 136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) NSViewAnimationEndFrameKey: [NSValue valueWithRect:targetRect] 137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) }; 138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 139eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::scoped_nsobject<NSViewAnimation> translate([[NSViewAnimation alloc] 140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) initWithViewAnimations:[NSArray arrayWithObject:animationDict]]); 141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) [translate setDuration:kAnimationDuration]; 142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) [translate startAnimation]; 143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)- (void)animateTransformFrom:(CATransform3D)fromValue 146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) useDelegate:(BOOL)useDelegate { 147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CABasicAnimation* animation = 148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) [CABasicAnimation animationWithKeyPath:@"transform"]; 149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) [animation setFromValue:[NSValue valueWithCATransform3D:fromValue]]; 150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (useDelegate) 151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) [animation setDelegate:self]; 152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) [animation setDuration:kAnimationDuration]; 154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) [CATransaction begin]; 155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) [CATransaction setValue:[NSNumber numberWithFloat:kAnimationDuration] 156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) forKey:kCATransactionAnimationDuration]; 157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) [dragLayer_ addAnimation:animation 158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) forKey:@"transform"]; 159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) [CATransaction commit]; 160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)- (void)clearAnimations { 163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) [dragLayer_ removeAllAnimations]; 164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!shrinking_) 165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(buttonToRestore_); 168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) [buttonToRestore_ setHidden:NO]; 169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) buttonToRestore_.reset(); 170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) shrinking_ = NO; 171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)- (void)animationDidStop:(CAAnimation*)anim 174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) finished:(BOOL)finished { 175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!finished) 176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(shrinking_); 179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) [self clearAnimations]; 180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) [dragLayer_ setContents:nil]; 181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) [[self view] setHidden:YES]; 182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)@end 185