| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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/cocoa/toolbar_controller.h" | 5 #import "chrome/browser/cocoa/toolbar_controller.h" |
| 6 | 6 |
| 7 #include "app/l10n_util_mac.h" | 7 #include "app/l10n_util_mac.h" |
| 8 #include "base/mac_util.h" | 8 #include "base/mac_util.h" |
| 9 #include "base/nsimage_cache_mac.h" | 9 #include "base/nsimage_cache_mac.h" |
| 10 #include "base/sys_string_conversions.h" | 10 #include "base/sys_string_conversions.h" |
| 11 #include "base/gfx/rect.h" | 11 #include "base/gfx/rect.h" |
| 12 #include "chrome/app/chrome_dll_resource.h" | 12 #include "chrome/app/chrome_dll_resource.h" |
| 13 #include "chrome/browser/autocomplete/autocomplete_edit_view.h" | 13 #include "chrome/browser/autocomplete/autocomplete_edit_view.h" |
| 14 #include "chrome/browser/bubble_positioner.h" | 14 #include "chrome/browser/bubble_positioner.h" |
| 15 #import "chrome/browser/cocoa/autocomplete_text_field.h" | 15 #import "chrome/browser/cocoa/autocomplete_text_field.h" |
| 16 #import "chrome/browser/cocoa/autocomplete_text_field_editor.h" | 16 #import "chrome/browser/cocoa/autocomplete_text_field_editor.h" |
| 17 #import "chrome/browser/cocoa/back_forward_menu_controller.h" | 17 #import "chrome/browser/cocoa/back_forward_menu_controller.h" |
| 18 #import "chrome/browser/cocoa/encoding_menu_controller_delegate_mac.h" | 18 #import "chrome/browser/cocoa/encoding_menu_controller_delegate_mac.h" |
| 19 #import "chrome/browser/cocoa/extensions/browser_actions_controller.h" |
| 19 #import "chrome/browser/cocoa/gradient_button_cell.h" | 20 #import "chrome/browser/cocoa/gradient_button_cell.h" |
| 20 #import "chrome/browser/cocoa/location_bar_view_mac.h" | 21 #import "chrome/browser/cocoa/location_bar_view_mac.h" |
| 21 #import "chrome/browser/cocoa/menu_button.h" | 22 #import "chrome/browser/cocoa/menu_button.h" |
| 22 #include "chrome/browser/profile.h" | 23 #include "chrome/browser/profile.h" |
| 23 #include "chrome/browser/search_engines/template_url_model.h" | 24 #include "chrome/browser/search_engines/template_url_model.h" |
| 24 #include "chrome/browser/toolbar_model.h" | 25 #include "chrome/browser/toolbar_model.h" |
| 25 #include "chrome/common/notification_details.h" | 26 #include "chrome/common/notification_details.h" |
| 26 #include "chrome/common/notification_observer.h" | 27 #include "chrome/common/notification_observer.h" |
| 27 #include "chrome/common/notification_type.h" | 28 #include "chrome/common/notification_type.h" |
| 28 #include "chrome/common/pref_names.h" | 29 #include "chrome/common/pref_names.h" |
| (...skipping 14 matching lines...) Expand all Loading... |
| 43 | 44 |
| 44 // Height of the toolbar in pixels when the bookmark bar is closed. | 45 // Height of the toolbar in pixels when the bookmark bar is closed. |
| 45 static const float kBaseToolbarHeight = 36.0; | 46 static const float kBaseToolbarHeight = 36.0; |
| 46 | 47 |
| 47 // Overlap (in pixels) between the toolbar and the bookmark bar. | 48 // Overlap (in pixels) between the toolbar and the bookmark bar. |
| 48 static const float kBookmarkBarOverlap = 6.0; | 49 static const float kBookmarkBarOverlap = 6.0; |
| 49 | 50 |
| 50 @interface ToolbarController(Private) | 51 @interface ToolbarController(Private) |
| 51 - (void)initCommandStatus:(CommandUpdater*)commands; | 52 - (void)initCommandStatus:(CommandUpdater*)commands; |
| 52 - (void)prefChanged:(std::wstring*)prefName; | 53 - (void)prefChanged:(std::wstring*)prefName; |
| 54 - (void)browserActionsChanged; |
| 55 - (void)adjustLocationAndGoPositionsBy:(CGFloat)dX; |
| 53 @end | 56 @end |
| 54 | 57 |
| 55 namespace { | 58 namespace { |
| 56 | 59 |
| 57 // A C++ class used to correctly position the omnibox. | 60 // A C++ class used to correctly position the omnibox. |
| 58 class BubblePositionerMac : public BubblePositioner { | 61 class BubblePositionerMac : public BubblePositioner { |
| 59 public: | 62 public: |
| 60 BubblePositionerMac(ToolbarController* controller) | 63 BubblePositionerMac(ToolbarController* controller) |
| 61 : controller_(controller) { } | 64 : controller_(controller) { } |
| 62 virtual ~BubblePositionerMac() { } | 65 virtual ~BubblePositionerMac() { } |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 119 commandObserver_->ObserveCommand(IDC_BOOKMARK_PAGE); | 122 commandObserver_->ObserveCommand(IDC_BOOKMARK_PAGE); |
| 120 } | 123 } |
| 121 return self; | 124 return self; |
| 122 } | 125 } |
| 123 | 126 |
| 124 - (void)dealloc { | 127 - (void)dealloc { |
| 125 // Make sure any code in the base class which assumes [self view] is | 128 // Make sure any code in the base class which assumes [self view] is |
| 126 // the "parent" view continues to work. | 129 // the "parent" view continues to work. |
| 127 hasToolbar_ = YES; | 130 hasToolbar_ = YES; |
| 128 | 131 |
| 132 [[NSNotificationCenter defaultCenter] removeObserver:self]; |
| 133 |
| 129 if (trackingArea_.get()) | 134 if (trackingArea_.get()) |
| 130 [[self view] removeTrackingArea:trackingArea_.get()]; | 135 [[self view] removeTrackingArea:trackingArea_.get()]; |
| 131 [super dealloc]; | 136 [super dealloc]; |
| 132 } | 137 } |
| 133 | 138 |
| 134 // Called after the view is done loading and the outlets have been hooked up. | 139 // Called after the view is done loading and the outlets have been hooked up. |
| 135 // Now we can hook up bridges that rely on UI objects such as the location | 140 // Now we can hook up bridges that rely on UI objects such as the location |
| 136 // bar and button state. | 141 // bar and button state. |
| 137 - (void)awakeFromNib { | 142 - (void)awakeFromNib { |
| 138 // A bug in AppKit (<rdar://7298597>, <http://openradar.me/7298597>) causes | 143 // A bug in AppKit (<rdar://7298597>, <http://openradar.me/7298597>) causes |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 171 | 176 |
| 172 // Create the controllers for the back/forward menus. | 177 // Create the controllers for the back/forward menus. |
| 173 backMenuController_.reset([[BackForwardMenuController alloc] | 178 backMenuController_.reset([[BackForwardMenuController alloc] |
| 174 initWithBrowser:browser_ | 179 initWithBrowser:browser_ |
| 175 modelType:BACK_FORWARD_MENU_TYPE_BACK | 180 modelType:BACK_FORWARD_MENU_TYPE_BACK |
| 176 button:backButton_]); | 181 button:backButton_]); |
| 177 forwardMenuController_.reset([[BackForwardMenuController alloc] | 182 forwardMenuController_.reset([[BackForwardMenuController alloc] |
| 178 initWithBrowser:browser_ | 183 initWithBrowser:browser_ |
| 179 modelType:BACK_FORWARD_MENU_TYPE_FORWARD | 184 modelType:BACK_FORWARD_MENU_TYPE_FORWARD |
| 180 button:forwardButton_]); | 185 button:forwardButton_]); |
| 181 | 186 browserActionsController_.reset([[BrowserActionsController alloc] |
| 187 initWithBrowser:browser_ |
| 188 containerView:browserActionContainerView_]); |
| 189 // When new browser actions are added/removed, the container view for them is |
| 190 // resized, necessitating the probable resizing of surrounding elements |
| 191 // handled by this controller. |
| 192 [[NSNotificationCenter defaultCenter] |
| 193 addObserver:self |
| 194 selector:@selector(browserActionsChanged) |
| 195 name:kBrowserActionsChangedNotification |
| 196 object:browserActionsController_]; |
| 197 [browserActionsController_ createButtons]; |
| 182 // For a popup window, the toolbar is really just a location bar | 198 // For a popup window, the toolbar is really just a location bar |
| 183 // (see override for [ToolbarController view], below). When going | 199 // (see override for [ToolbarController view], below). When going |
| 184 // fullscreen, we remove the toolbar controller's view from the view | 200 // fullscreen, we remove the toolbar controller's view from the view |
| 185 // hierarchy. Calling [locationBar_ removeFromSuperview] when going | 201 // hierarchy. Calling [locationBar_ removeFromSuperview] when going |
| 186 // fullscreen causes it to get released, making us unhappy | 202 // fullscreen causes it to get released, making us unhappy |
| 187 // (http://crbug.com/18551). We avoid the problem by incrementing | 203 // (http://crbug.com/18551). We avoid the problem by incrementing |
| 188 // the retain count of the location bar; use of the scoped object | 204 // the retain count of the location bar; use of the scoped object |
| 189 // helps us remember to release it. | 205 // helps us remember to release it. |
| 190 locationBarRetainer_.reset([locationBar_ retain]); | 206 locationBarRetainer_.reset([locationBar_ retain]); |
| 191 trackingArea_.reset( | 207 trackingArea_.reset( |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 355 [autocompleteTextFieldEditor_.get() setFieldEditor:YES]; | 371 [autocompleteTextFieldEditor_.get() setFieldEditor:YES]; |
| 356 return autocompleteTextFieldEditor_.get(); | 372 return autocompleteTextFieldEditor_.get(); |
| 357 } | 373 } |
| 358 return nil; | 374 return nil; |
| 359 } | 375 } |
| 360 | 376 |
| 361 // Returns an array of views in the order of the outlets above. | 377 // Returns an array of views in the order of the outlets above. |
| 362 - (NSArray*)toolbarViews { | 378 - (NSArray*)toolbarViews { |
| 363 return [NSArray arrayWithObjects:backButton_, forwardButton_, reloadButton_, | 379 return [NSArray arrayWithObjects:backButton_, forwardButton_, reloadButton_, |
| 364 homeButton_, starButton_, goButton_, pageButton_, wrenchButton_, | 380 homeButton_, starButton_, goButton_, pageButton_, wrenchButton_, |
| 365 locationBar_, encodingMenu_, nil]; | 381 locationBar_, encodingMenu_, browserActionContainerView_, nil]; |
| 366 } | 382 } |
| 367 | 383 |
| 368 // Moves |rect| to the right by |delta|, keeping the right side fixed by | 384 // Moves |rect| to the right by |delta|, keeping the right side fixed by |
| 369 // shrinking the width to compensate. Passing a negative value for |deltaX| | 385 // shrinking the width to compensate. Passing a negative value for |deltaX| |
| 370 // moves to the left and increases the width. | 386 // moves to the left and increases the width. |
| 371 - (NSRect)adjustRect:(NSRect)rect byAmount:(float)deltaX { | 387 - (NSRect)adjustRect:(NSRect)rect byAmount:(CGFloat)deltaX { |
| 372 NSRect frame = NSOffsetRect(rect, deltaX, 0); | 388 NSRect frame = NSOffsetRect(rect, deltaX, 0); |
| 373 frame.size.width -= deltaX; | 389 frame.size.width -= deltaX; |
| 374 return frame; | 390 return frame; |
| 375 } | 391 } |
| 376 | 392 |
| 377 // Computes the padding between the buttons that should have a separation from | 393 // Computes the padding between the buttons that should have a separation from |
| 378 // the positions in the nib. Since the forward and reload buttons are always | 394 // the positions in the nib. Since the forward and reload buttons are always |
| 379 // visible, we use those buttons as the canonical spacing. | 395 // visible, we use those buttons as the canonical spacing. |
| 380 - (float)interButtonSpacing { | 396 - (CGFloat)interButtonSpacing { |
| 381 NSRect forwardFrame = [forwardButton_ frame]; | 397 NSRect forwardFrame = [forwardButton_ frame]; |
| 382 NSRect reloadFrame = [reloadButton_ frame]; | 398 NSRect reloadFrame = [reloadButton_ frame]; |
| 383 DCHECK(NSMinX(reloadFrame) > NSMaxX(forwardFrame)); | 399 DCHECK(NSMinX(reloadFrame) > NSMaxX(forwardFrame)); |
| 384 return NSMinX(reloadFrame) - NSMaxX(forwardFrame); | 400 return NSMinX(reloadFrame) - NSMaxX(forwardFrame); |
| 385 } | 401 } |
| 386 | 402 |
| 387 // Show or hide the home button based on the pref. | 403 // Show or hide the home button based on the pref. |
| 388 - (void)showOptionalHomeButton { | 404 - (void)showOptionalHomeButton { |
| 389 // Ignore this message if only showing the URL bar. | 405 // Ignore this message if only showing the URL bar. |
| 390 if (!hasToolbar_) | 406 if (!hasToolbar_) |
| 391 return; | 407 return; |
| 392 BOOL hide = showHomeButton_.GetValue() ? NO : YES; | 408 BOOL hide = showHomeButton_.GetValue() ? NO : YES; |
| 393 if (hide == [homeButton_ isHidden]) | 409 if (hide == [homeButton_ isHidden]) |
| 394 return; // Nothing to do, view state matches pref state. | 410 return; // Nothing to do, view state matches pref state. |
| 395 | 411 |
| 396 // Always shift the star and text field by the width of the home button plus | 412 // Always shift the star and text field by the width of the home button plus |
| 397 // the appropriate gap width. If we're hiding the button, we have to | 413 // the appropriate gap width. If we're hiding the button, we have to |
| 398 // reverse the direction of the movement (to the left). | 414 // reverse the direction of the movement (to the left). |
| 399 float moveX = [self interButtonSpacing] + [homeButton_ frame].size.width; | 415 CGFloat moveX = [self interButtonSpacing] + [homeButton_ frame].size.width; |
| 400 if (hide) | 416 if (hide) |
| 401 moveX *= -1; // Reverse the direction of the move. | 417 moveX *= -1; // Reverse the direction of the move. |
| 402 | 418 |
| 403 [starButton_ setFrame:NSOffsetRect([starButton_ frame], moveX, 0)]; | 419 [starButton_ setFrame:NSOffsetRect([starButton_ frame], moveX, 0)]; |
| 404 [locationBar_ setFrame:[self adjustRect:[locationBar_ frame] | 420 [locationBar_ setFrame:[self adjustRect:[locationBar_ frame] |
| 405 byAmount:moveX]]; | 421 byAmount:moveX]]; |
| 406 [homeButton_ setHidden:hide]; | 422 [homeButton_ setHidden:hide]; |
| 407 } | 423 } |
| 408 | 424 |
| 409 // Show or hide the page and wrench buttons based on the pref. | 425 // Show or hide the page and wrench buttons based on the pref. |
| 410 - (void)showOptionalPageWrenchButtons { | 426 - (void)showOptionalPageWrenchButtons { |
| 411 // Ignore this message if only showing the URL bar. | 427 // Ignore this message if only showing the URL bar. |
| 412 if (!hasToolbar_) | 428 if (!hasToolbar_) |
| 413 return; | 429 return; |
| 414 DCHECK([pageButton_ isHidden] == [wrenchButton_ isHidden]); | 430 DCHECK([pageButton_ isHidden] == [wrenchButton_ isHidden]); |
| 415 BOOL hide = showPageOptionButtons_.GetValue() ? NO : YES; | 431 BOOL hide = showPageOptionButtons_.GetValue() ? NO : YES; |
| 416 if (hide == [pageButton_ isHidden]) | 432 if (hide == [pageButton_ isHidden]) |
| 417 return; // Nothing to do, view state matches pref state. | 433 return; // Nothing to do, view state matches pref state. |
| 418 | 434 |
| 419 // Shift the go button and resize the text field by the width of the | 435 // Shift the go button and resize the text field by the width of the |
| 420 // page/wrench buttons plus two times the gap width. If we're showing the | 436 // page/wrench buttons plus two times the gap width. If we're showing the |
| 421 // buttons, we have to reverse the direction of movement (to the left). Unlike | 437 // buttons, we have to reverse the direction of movement (to the left). Unlike |
| 422 // the home button above, we only ever have to resize the text field, we don't | 438 // the home button above, we only ever have to resize the text field, we don't |
| 423 // have to move it. | 439 // have to move it. |
| 424 float moveX = 2 * [self interButtonSpacing] + NSWidth([pageButton_ frame]) + | 440 CGFloat moveX = 2 * [self interButtonSpacing] + NSWidth([pageButton_ frame]) + |
| 425 NSWidth([wrenchButton_ frame]); | 441 NSWidth([wrenchButton_ frame]); |
| 442 |
| 443 // Adjust for the extra unit of inter-button spacing added when the page and |
| 444 // wrench buttons are hidden. |
| 445 if ([browserActionsController_ buttonCount] > 0) |
| 446 moveX -= [self interButtonSpacing]; |
| 447 |
| 426 if (!hide) | 448 if (!hide) |
| 427 moveX *= -1; // Reverse the direction of the move. | 449 moveX *= -1; // Reverse the direction of the move. |
| 428 [goButton_ setFrame:NSOffsetRect([goButton_ frame], moveX, 0)]; | 450 |
| 429 NSRect locationFrame = [locationBar_ frame]; | 451 [self adjustLocationAndGoPositionsBy:moveX]; |
| 430 locationFrame.size.width += moveX; | 452 [browserActionContainerView_ setFrame:NSOffsetRect( |
| 431 [locationBar_ setFrame:locationFrame]; | 453 [browserActionContainerView_ frame], moveX, 0)]; |
| 432 | 454 |
| 433 [pageButton_ setHidden:hide]; | 455 [pageButton_ setHidden:hide]; |
| 434 [wrenchButton_ setHidden:hide]; | 456 [wrenchButton_ setHidden:hide]; |
| 435 } | 457 } |
| 436 | 458 |
| 437 - (void)prefChanged:(std::wstring*)prefName { | 459 - (void)prefChanged:(std::wstring*)prefName { |
| 438 if (!prefName) return; | 460 if (!prefName) return; |
| 439 if (*prefName == prefs::kShowHomeButton) { | 461 if (*prefName == prefs::kShowHomeButton) { |
| 440 [self showOptionalHomeButton]; | 462 [self showOptionalHomeButton]; |
| 441 } else if (*prefName == prefs::kShowPageOptionsButtons) { | 463 } else if (*prefName == prefs::kShowPageOptionsButtons) { |
| 442 [self showOptionalPageWrenchButtons]; | 464 [self showOptionalPageWrenchButtons]; |
| 443 } | 465 } |
| 444 } | 466 } |
| 445 | 467 |
| 468 - (void)browserActionsChanged { |
| 469 // Calculate the new width. |
| 470 int buttonCount = [browserActionsController_ buttonCount]; |
| 471 |
| 472 CGFloat width = 0.0; |
| 473 if (buttonCount > 0) { |
| 474 width = (buttonCount * |
| 475 (kBrowserActionWidth + kBrowserActionButtonPadding)) - |
| 476 kBrowserActionButtonPadding; // No padding after last button. |
| 477 } |
| 478 |
| 479 NSRect containerFrame = [browserActionContainerView_ frame]; |
| 480 CGFloat buttonSpacing = [self interButtonSpacing]; |
| 481 CGFloat dX = containerFrame.size.width - width; |
| 482 containerFrame.size.width = width; |
| 483 |
| 484 bool addingButton = (dX < 0); |
| 485 // If a button is being added, add spacing inward by negating the value. |
| 486 if (addingButton) |
| 487 buttonSpacing *= -1; |
| 488 |
| 489 // If the first button is being added or the last button is being removed, |
| 490 // then account for the right padding it will need. |
| 491 if ((buttonCount == 1 && addingButton) || |
| 492 (buttonCount == 0 && !addingButton)) { |
| 493 dX += buttonSpacing; |
| 494 // The offset of the buttons from the right side will be one button spacing |
| 495 // unit more than if the wrench and page buttons were shown. |
| 496 if ([pageButton_ isHidden] && [wrenchButton_ isHidden]) { |
| 497 dX += buttonSpacing; |
| 498 } |
| 499 } |
| 500 |
| 501 [browserActionContainerView_ setFrame:NSOffsetRect(containerFrame, dX, 0)]; |
| 502 [self adjustLocationAndGoPositionsBy:dX]; |
| 503 } |
| 504 |
| 505 - (void)adjustLocationAndGoPositionsBy:(CGFloat)dX { |
| 506 [goButton_ setFrame:NSOffsetRect([goButton_ frame], dX, 0)]; |
| 507 NSRect locationFrame = [locationBar_ frame]; |
| 508 locationFrame.size.width += dX; |
| 509 [locationBar_ setFrame:locationFrame]; |
| 510 } |
| 511 |
| 446 - (NSRect)starButtonInWindowCoordinates { | 512 - (NSRect)starButtonInWindowCoordinates { |
| 447 return [[[starButton_ window] contentView] convertRect:[starButton_ bounds] | 513 return [[[starButton_ window] contentView] convertRect:[starButton_ bounds] |
| 448 fromView:starButton_]; | 514 fromView:starButton_]; |
| 449 } | 515 } |
| 450 | 516 |
| 451 - (void)setShouldBeCompressed:(BOOL)compressed { | 517 - (void)setShouldBeCompressed:(BOOL)compressed { |
| 452 CGFloat newToolbarHeight = kBaseToolbarHeight; | 518 CGFloat newToolbarHeight = kBaseToolbarHeight; |
| 453 if (compressed) | 519 if (compressed) |
| 454 newToolbarHeight -= kBookmarkBarOverlap; | 520 newToolbarHeight -= kBookmarkBarOverlap; |
| 455 | 521 |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 524 | 590 |
| 525 NSRect r = NSMakeRect(minX, NSMinY(locationFrame), maxX - minX, | 591 NSRect r = NSMakeRect(minX, NSMinY(locationFrame), maxX - minX, |
| 526 NSHeight(locationFrame)); | 592 NSHeight(locationFrame)); |
| 527 gfx::Rect stack_bounds( | 593 gfx::Rect stack_bounds( |
| 528 NSRectToCGRect([[self view] convertRect:r toView:nil])); | 594 NSRectToCGRect([[self view] convertRect:r toView:nil])); |
| 529 // Inset the bounds to just inside the visible edges (see comment above). | 595 // Inset the bounds to just inside the visible edges (see comment above). |
| 530 stack_bounds.Inset(kLocationStackEdgeWidth, 0); | 596 stack_bounds.Inset(kLocationStackEdgeWidth, 0); |
| 531 return stack_bounds; | 597 return stack_bounds; |
| 532 } | 598 } |
| 533 @end | 599 @end |
| OLD | NEW |