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