Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(446)

Side by Side Diff: chrome/browser/ui/cocoa/extensions/browser_actions_container_view.mm

Issue 2629723005: [Mac] Fix bugs in resizing the browser actions area next to the omnibox. (Closed)
Patch Set: Format Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #import "chrome/browser/ui/cocoa/extensions/browser_actions_container_view.h" 5 #import "chrome/browser/ui/cocoa/extensions/browser_actions_container_view.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <utility> 8 #include <utility>
9 9
10 #import "chrome/browser/ui/cocoa/l10n_util.h" 10 #import "chrome/browser/ui/cocoa/l10n_util.h"
(...skipping 14 matching lines...) Expand all
25 NSString* const kTranslationWithDelta = 25 NSString* const kTranslationWithDelta =
26 @"TranslationWithDelta"; 26 @"TranslationWithDelta";
27 NSString* const kBrowserActionsContainerReceivedKeyEvent = 27 NSString* const kBrowserActionsContainerReceivedKeyEvent =
28 @"BrowserActionsContainerReceivedKeyEvent"; 28 @"BrowserActionsContainerReceivedKeyEvent";
29 NSString* const kBrowserActionsContainerKeyEventKey = 29 NSString* const kBrowserActionsContainerKeyEventKey =
30 @"BrowserActionsContainerKeyEventKey"; 30 @"BrowserActionsContainerKeyEventKey";
31 31
32 namespace { 32 namespace {
33 const CGFloat kAnimationDuration = 0.2; 33 const CGFloat kAnimationDuration = 0.2;
34 const CGFloat kGrippyWidth = 3.0; 34 const CGFloat kGrippyWidth = 3.0;
35 const CGFloat kMinimumContainerWidth = 3.0;
36 } // namespace 35 } // namespace
37 36
38 @interface BrowserActionsContainerView(Private) 37 @interface BrowserActionsContainerView(Private)
39 // Returns the cursor that should be shown when hovering over the grippy based 38 // Returns the cursor that should be shown when hovering over the grippy based
40 // on |canDragLeft_| and |canDragRight_|. 39 // on |canDragLeft_| and |canDragRight_|.
41 - (NSCursor*)appropriateCursorForGrippy; 40 - (NSCursor*)appropriateCursorForGrippy;
42
43 // Returns the maximum allowed size for the container.
44 - (CGFloat)maxAllowedWidth;
45 @end 41 @end
46 42
47 @implementation BrowserActionsContainerView 43 @implementation BrowserActionsContainerView
48 44
49 @synthesize canDragLeft = canDragLeft_; 45 @synthesize minWidth = minWidth_;
50 @synthesize canDragRight = canDragRight_; 46 @synthesize maxWidth = maxWidth_;
51 @synthesize grippyPinned = grippyPinned_; 47 @synthesize grippyPinned = grippyPinned_;
52 @synthesize maxDesiredWidth = maxDesiredWidth_;
53 @synthesize userIsResizing = userIsResizing_; 48 @synthesize userIsResizing = userIsResizing_;
54 @synthesize delegate = delegate_;
55 49
56 #pragma mark - 50 #pragma mark -
57 #pragma mark Overridden Class Functions 51 #pragma mark Overridden Class Functions
58 52
59 - (id)initWithFrame:(NSRect)frameRect { 53 - (id)initWithFrame:(NSRect)frameRect {
60 if ((self = [super initWithFrame:frameRect])) { 54 if ((self = [super initWithFrame:frameRect])) {
61 grippyRect_ = NSMakeRect(0.0, 0.0, kGrippyWidth, NSHeight([self bounds])); 55 grippyRect_ = NSMakeRect(0.0, 0.0, kGrippyWidth, NSHeight([self bounds]));
62 if (cocoa_l10n_util::ShouldDoExperimentalRTLLayout()) 56 if (cocoa_l10n_util::ShouldDoExperimentalRTLLayout())
63 grippyRect_.origin.x = NSWidth(frameRect) - NSWidth(grippyRect_); 57 grippyRect_.origin.x = NSWidth(frameRect) - NSWidth(grippyRect_);
64 58
65 canDragLeft_ = YES;
66 canDragRight_ = YES;
67 resizable_ = YES; 59 resizable_ = YES;
68 60
69 resizeAnimation_.reset([[NSViewAnimation alloc] init]); 61 resizeAnimation_.reset([[NSViewAnimation alloc] init]);
70 [resizeAnimation_ setDuration:kAnimationDuration]; 62 [resizeAnimation_ setDuration:kAnimationDuration];
71 [resizeAnimation_ setAnimationBlockingMode:NSAnimationNonblocking]; 63 [resizeAnimation_ setAnimationBlockingMode:NSAnimationNonblocking];
72 [resizeAnimation_ setDelegate:self]; 64 [resizeAnimation_ setDelegate:self];
73 65
74 [self setHidden:YES]; 66 [self setHidden:YES];
75 } 67 }
76 return self; 68 return self;
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
172 } 164 }
173 165
174 - (BOOL)acceptsFirstResponder { 166 - (BOOL)acceptsFirstResponder {
175 // The overflow container needs to receive key events to handle in-item 167 // The overflow container needs to receive key events to handle in-item
176 // navigation. The top-level container should not become first responder, 168 // navigation. The top-level container should not become first responder,
177 // allowing focus travel to proceed to the first action. 169 // allowing focus travel to proceed to the first action.
178 return isOverflow_; 170 return isOverflow_;
179 } 171 }
180 172
181 - (void)mouseDown:(NSEvent*)theEvent { 173 - (void)mouseDown:(NSEvent*)theEvent {
182 initialDragPoint_ = [self convertPoint:[theEvent locationInWindow] 174 NSPoint location =
183 fromView:nil]; 175 [self convertPoint:[theEvent locationInWindow] fromView:nil];
184 if (!resizable_ || 176 if (!resizable_ || !NSMouseInRect(location, grippyRect_, [self isFlipped]))
185 !NSMouseInRect(initialDragPoint_, grippyRect_, [self isFlipped]))
186 return; 177 return;
187 178
179 dragOffset_ = location.x - (cocoa_l10n_util::ShouldDoExperimentalRTLLayout()
180 ? NSWidth(self.frame)
181 : 0);
182
188 userIsResizing_ = YES; 183 userIsResizing_ = YES;
189 184
190 [[self appropriateCursorForGrippy] push]; 185 [[self appropriateCursorForGrippy] push];
191 // Disable cursor rects so that the Omnibox and other UI elements don't push 186 // Disable cursor rects so that the Omnibox and other UI elements don't push
192 // cursors while the user is dragging. The cursor should be grippy until 187 // cursors while the user is dragging. The cursor should be grippy until
193 // the |-mouseUp:| message is received. 188 // the |-mouseUp:| message is received.
194 [[self window] disableCursorRects]; 189 [[self window] disableCursorRects];
195 190
196 [[NSNotificationCenter defaultCenter] 191 [[NSNotificationCenter defaultCenter]
197 postNotificationName:kBrowserActionGrippyDragStartedNotification 192 postNotificationName:kBrowserActionGrippyDragStartedNotification
(...skipping 10 matching lines...) Expand all
208 userIsResizing_ = NO; 203 userIsResizing_ = NO;
209 [[NSNotificationCenter defaultCenter] 204 [[NSNotificationCenter defaultCenter]
210 postNotificationName:kBrowserActionGrippyDragFinishedNotification 205 postNotificationName:kBrowserActionGrippyDragFinishedNotification
211 object:self]; 206 object:self];
212 } 207 }
213 208
214 - (void)mouseDragged:(NSEvent*)theEvent { 209 - (void)mouseDragged:(NSEvent*)theEvent {
215 if (!userIsResizing_) 210 if (!userIsResizing_)
216 return; 211 return;
217 212
218 NSPoint location = [self convertPoint:[theEvent locationInWindow] 213 const CGFloat translation =
219 fromView:nil]; 214 [self convertPoint:[theEvent locationInWindow] fromView:nil].x -
220 NSRect containerFrame = [self frame]; 215 dragOffset_;
221 CGFloat dX = [theEvent deltaX]; 216 const CGFloat targetWidth = (cocoa_l10n_util::ShouldDoExperimentalRTLLayout()
222 CGFloat withDelta = location.x - dX; 217 ? translation
223 BOOL isRTL = cocoa_l10n_util::ShouldDoExperimentalRTLLayout(); 218 : NSWidth(self.frame) - translation);
224 219
225 CGFloat maxAllowedWidth = [self maxAllowedWidth]; 220 [self resizeToWidth:targetWidth animate:NO];
226
227 const CGFloat maxWidth = std::min(maxAllowedWidth, maxDesiredWidth_);
228 CGFloat newWidth = NSWidth(containerFrame) + (isRTL ? dX : -dX);
229 newWidth = std::min(std::max(newWidth, kMinimumContainerWidth), maxWidth);
230
231 BOOL canGrow = NSWidth(containerFrame) < maxWidth;
232 BOOL canShrink = NSWidth(containerFrame) > kMinimumContainerWidth;
233
234 canDragLeft_ =
235 withDelta <= initialDragPoint_.x && (isRTL ? canShrink : canGrow);
236 canDragRight_ =
237 (withDelta >= initialDragPoint_.x) && (isRTL ? canGrow : canShrink);
238 if ((dX < 0.0 && !canDragLeft_) || (dX > 0.0 && !canDragRight_) ||
239 fabs(dX) < FLT_EPSILON)
240 return;
241
242 grippyPinned_ = newWidth >= maxAllowedWidth;
243 if (!isRTL)
244 containerFrame.origin.x += dX;
245 containerFrame.size.width = newWidth;
246
247 [self setFrame:containerFrame];
248 [self setNeedsDisplay:YES];
249 221
250 [[NSNotificationCenter defaultCenter] 222 [[NSNotificationCenter defaultCenter]
251 postNotificationName:kBrowserActionGrippyDraggingNotification 223 postNotificationName:kBrowserActionGrippyDraggingNotification
252 object:self]; 224 object:self];
253 } 225 }
254 226
255 - (void)animationDidEnd:(NSAnimation*)animation { 227 - (void)animationDidEnd:(NSAnimation*)animation {
256 // We notify asynchronously so that the animation fully finishes before any 228 // We notify asynchronously so that the animation fully finishes before any
257 // listeners do work. 229 // listeners do work.
258 [self performSelector:@selector(notifyAnimationEnded) 230 [self performSelector:@selector(notifyAnimationEnded)
(...skipping 16 matching lines...) Expand all
275 } 247 }
276 248
277 - (ViewID)viewID { 249 - (ViewID)viewID {
278 return VIEW_ID_BROWSER_ACTION_TOOLBAR; 250 return VIEW_ID_BROWSER_ACTION_TOOLBAR;
279 } 251 }
280 252
281 #pragma mark - 253 #pragma mark -
282 #pragma mark Public Methods 254 #pragma mark Public Methods
283 255
284 - (void)resizeToWidth:(CGFloat)width animate:(BOOL)animate { 256 - (void)resizeToWidth:(CGFloat)width animate:(BOOL)animate {
285 width = std::max(width, kMinimumContainerWidth); 257 width = std::min(std::max(width, minWidth_), maxWidth_);
258
286 NSRect newFrame = [self frame]; 259 NSRect newFrame = [self frame];
260 if (!cocoa_l10n_util::ShouldDoExperimentalRTLLayout())
261 newFrame.origin.x += NSWidth(newFrame) - width;
262 newFrame.size.width = width;
287 263
288 CGFloat maxAllowedWidth = [self maxAllowedWidth]; 264 grippyPinned_ = width == maxWidth_;
289 width = std::min(maxAllowedWidth, width);
290
291 if (cocoa_l10n_util::ShouldDoExperimentalRTLLayout()) {
292 newFrame.size.width = width;
293 } else {
294 CGFloat dX = NSWidth(newFrame) - width;
295 newFrame.size.width = width;
296 newFrame.origin.x += dX;
297 }
298
299 grippyPinned_ = width == maxAllowedWidth;
300 265
301 [self stopAnimation]; 266 [self stopAnimation];
302 267
303 if (animate) { 268 if (animate) {
304 NSDictionary* animationDictionary = @{ 269 NSDictionary* animationDictionary = @{
305 NSViewAnimationTargetKey : self, 270 NSViewAnimationTargetKey : self,
306 NSViewAnimationStartFrameKey : [NSValue valueWithRect:[self frame]], 271 NSViewAnimationStartFrameKey : [NSValue valueWithRect:[self frame]],
307 NSViewAnimationEndFrameKey : [NSValue valueWithRect:newFrame] 272 NSViewAnimationEndFrameKey : [NSValue valueWithRect:newFrame]
308 }; 273 };
309 [resizeAnimation_ setViewAnimations:@[ animationDictionary ]]; 274 [resizeAnimation_ setViewAnimations:@[ animationDictionary ]];
(...skipping 26 matching lines...) Expand all
336 if ([resizeAnimation_ isAnimating]) 301 if ([resizeAnimation_ isAnimating])
337 [resizeAnimation_ stopAnimation]; 302 [resizeAnimation_ stopAnimation];
338 } 303 }
339 304
340 #pragma mark - 305 #pragma mark -
341 #pragma mark Private Methods 306 #pragma mark Private Methods
342 307
343 // Returns the cursor to display over the grippy hover region depending on the 308 // Returns the cursor to display over the grippy hover region depending on the
344 // current drag state. 309 // current drag state.
345 - (NSCursor*)appropriateCursorForGrippy { 310 - (NSCursor*)appropriateCursorForGrippy {
346 NSCursor* retVal; 311 if (resizable_) {
347 if (!resizable_ || (!canDragLeft_ && !canDragRight_)) { 312 const CGFloat width = NSWidth(self.frame);
348 retVal = [NSCursor arrowCursor]; 313 const BOOL isRTL = cocoa_l10n_util::ShouldDoExperimentalRTLLayout();
349 } else if (!canDragLeft_) { 314 const BOOL canDragLeft = width != (isRTL ? minWidth_ : maxWidth_);
350 retVal = [NSCursor resizeRightCursor]; 315 const BOOL canDragRight = width != (isRTL ? maxWidth_ : minWidth_);
351 } else if (!canDragRight_) { 316
352 retVal = [NSCursor resizeLeftCursor]; 317 if (canDragLeft && canDragRight)
353 } else { 318 return [NSCursor resizeLeftRightCursor];
354 retVal = [NSCursor resizeLeftRightCursor]; 319 if (canDragLeft)
320 return [NSCursor resizeLeftCursor];
321 if (canDragRight)
322 return [NSCursor resizeRightCursor];
355 } 323 }
356 return retVal; 324 return [NSCursor arrowCursor];
357 }
358
359 - (CGFloat)maxAllowedWidth {
360 return delegate_ ? delegate_->GetMaxAllowedWidth() : CGFLOAT_MAX;
361 } 325 }
362 326
363 @end 327 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698