Index: chrome/browser/cocoa/toolbar_controller.mm |
=================================================================== |
--- chrome/browser/cocoa/toolbar_controller.mm (revision 20018) |
+++ chrome/browser/cocoa/toolbar_controller.mm (working copy) |
@@ -8,7 +8,13 @@ |
#include "base/sys_string_conversions.h" |
#include "chrome/app/chrome_dll_resource.h" |
#import "chrome/browser/cocoa/location_bar_view_mac.h" |
+#include "chrome/browser/profile.h" |
#include "chrome/browser/toolbar_model.h" |
+#include "chrome/common/notification_details.h" |
+#include "chrome/common/notification_observer.h" |
+#include "chrome/common/notification_type.h" |
+#include "chrome/common/pref_names.h" |
+#include "chrome/common/pref_service.h" |
// Names of images in the bundle for the star icon (normal and 'starred'). |
static NSString* const kStarImageName = @"star"; |
@@ -40,8 +46,30 @@ |
@interface ToolbarController(Private) |
- (void)initCommandStatus:(CommandUpdater*)commands; |
+- (void)prefChanged:(std::wstring*)prefName; |
@end |
+namespace ToolbarControllerInternal { |
+ |
+// A C++ class registered for changes in preferences. Bridges the |
+// notification back to the BWC. |
rohitrao (ping after 24h)
2009/07/07 18:10:46
s/BWC/ToolbarController/ ?
pink (ping after 24hrs)
2009/07/07 18:12:17
Done.
|
+class PrefObserverBridge : public NotificationObserver { |
+ public: |
+ PrefObserverBridge(ToolbarController* controller) |
+ : controller_(controller) { } |
+ // Overridden from NotificationObserver: |
+ virtual void Observe(NotificationType type, |
+ const NotificationSource& source, |
+ const NotificationDetails& details) { |
+ if (type == NotificationType::PREF_CHANGED) |
+ [controller_ prefChanged:Details<std::wstring>(details).ptr()]; |
+ } |
+ private: |
+ ToolbarController* controller_; // weak, owns us |
+}; |
+ |
+} // namespace |
+ |
@implementation ToolbarController |
- (id)initWithModel:(ToolbarModel*)model |
@@ -73,6 +101,16 @@ |
locationBarView_.reset(new LocationBarViewMac(locationBar_, commands_, |
toolbarModel_, profile_)); |
[locationBar_ setFont:[NSFont systemFontOfSize:[NSFont systemFontSize]]]; |
+ |
+ // Register pref observers for the optional home and page/options buttons |
+ // and then add them to the toolbar them based on those prefs. |
+ prefObserver_.reset(new ToolbarControllerInternal::PrefObserverBridge(self)); |
+ PrefService* prefs = profile_->GetPrefs(); |
+ showHomeButton_.Init(prefs::kShowHomeButton, prefs, prefObserver_.get()); |
+ showPageOptionButtons_.Init(prefs::kShowPageOptionsButtons, prefs, |
+ prefObserver_.get()); |
+ [self showOptionalHomeButton]; |
+ [self showOptionalPageWrenchButtons]; |
} |
- (LocationBar*)locationBar { |
@@ -97,7 +135,7 @@ |
button = forwardButton_; |
break; |
case IDC_HOME: |
- // TODO(pinkerton): add home button |
+ button = homeButton_; |
break; |
case IDC_STAR: |
button = starButton_; |
@@ -112,9 +150,8 @@ |
[backButton_ setEnabled:commands->IsCommandEnabled(IDC_BACK) ? YES : NO]; |
[forwardButton_ |
setEnabled:commands->IsCommandEnabled(IDC_FORWARD) ? YES : NO]; |
- [reloadButton_ |
- setEnabled:commands->IsCommandEnabled(IDC_RELOAD) ? YES : NO]; |
- // TODO(pinkerton): Add home button. |
+ [reloadButton_ setEnabled:commands->IsCommandEnabled(IDC_RELOAD) ? YES : NO]; |
+ [homeButton_ setEnabled:commands->IsCommandEnabled(IDC_HOME) ? YES : NO]; |
[starButton_ setEnabled:commands->IsCommandEnabled(IDC_STAR) ? YES : NO]; |
} |
@@ -161,7 +198,92 @@ |
// Returns an array of views in the order of the outlets above. |
- (NSArray*)toolbarViews { |
return [NSArray arrayWithObjects:backButton_, forwardButton_, reloadButton_, |
- starButton_, goButton_, locationBar_, nil]; |
+ homeButton_, starButton_, goButton_, pageButton_, wrenchButton_, |
+ locationBar_, nil]; |
} |
+// Moves |rect| to the right by |delta|, keeping the right side fixed by |
+// shrinking the width to compensate. Passing a negative value for |deltaX| |
+// moves to the left and increases the width. |
+- (NSRect)adjustRect:(NSRect)rect byAmount:(float)deltaX { |
+ NSRect frame = NSOffsetRect(rect, deltaX, 0); |
+ frame.size.width -= deltaX; |
+ return frame; |
+} |
+ |
+// Computes the padding between the buttons that should have a separation from |
+// the positions in the nib. Since the forward and reload buttons are always |
+// visible, we use those buttons as the canonical spacing. |
+- (float)interButtonSpacing { |
+ NSRect forwardFrame = [forwardButton_ frame]; |
+ NSRect reloadFrame = [reloadButton_ frame]; |
+ DCHECK(NSMinX(reloadFrame) > NSMaxX(forwardFrame)); |
+ return NSMinX(reloadFrame) - NSMaxX(forwardFrame); |
+} |
+ |
+// Show or hide the home button based on the pref. |
+- (void)showOptionalHomeButton { |
+ BOOL hide = showHomeButton_.GetValue() ? NO : YES; |
+ if (hide == [homeButton_ isHidden]) |
+ return; // Nothing to do, view state matches pref state. |
+ |
+ // Always shift the star and text field by the width of the home button plus |
+ // the appropriate gap width. If we're hiding the button, we have to |
+ // reverse the direction of the movement (to the left). |
+ float moveX = [self interButtonSpacing] + [homeButton_ frame].size.width; |
+ if (hide) |
+ moveX *= -1; // Reverse the direction of the move. |
+ |
+ [starButton_ setFrame:NSOffsetRect([starButton_ frame], moveX, 0)]; |
+ [locationBar_ setFrame:[self adjustRect:[locationBar_ frame] |
+ byAmount:moveX]]; |
+ [homeButton_ setHidden:hide]; |
+} |
+ |
+// Show or hide the page and wrench buttons based on the pref. |
+- (void)showOptionalPageWrenchButtons { |
+ DCHECK([pageButton_ isHidden] == [wrenchButton_ isHidden]); |
+ BOOL hide = showPageOptionButtons_.GetValue() ? NO : YES; |
+ if (hide == [pageButton_ isHidden]) |
+ return; // Nothing to do, view state matches pref state. |
+ |
+ // Shift the go button and resize the text field by the width of the |
+ // page/wrench buttons plus two times the gap width. If we're showing the |
+ // buttons, we have to reverse the direction of movement (to the left). Unlike |
+ // the home button above, we only ever have to resize the text field, we don't |
+ // have to move it. |
+ float moveX = 2 * [self interButtonSpacing] + NSWidth([pageButton_ frame]) + |
+ NSWidth([wrenchButton_ frame]); |
+ if (!hide) |
+ moveX *= -1; // Reverse the direction of the move. |
+ [goButton_ setFrame:NSOffsetRect([goButton_ frame], moveX, 0)]; |
+ NSRect locationFrame = [locationBar_ frame]; |
+ locationFrame.size.width += moveX; |
+ [locationBar_ setFrame:locationFrame]; |
+ |
+ [pageButton_ setHidden:hide]; |
+ [wrenchButton_ setHidden:hide]; |
+} |
+ |
+- (void)prefChanged:(std::wstring*)prefName { |
+ if (!prefName) return; |
+ if (*prefName == prefs::kShowHomeButton) { |
+ [self showOptionalHomeButton]; |
+ } else if (*prefName == prefs::kShowPageOptionsButtons) { |
+ [self showOptionalPageWrenchButtons]; |
+ } |
+} |
+ |
+- (IBAction)showPageMenu:(id)sender { |
+ [NSMenu popUpContextMenu:pageMenu_ |
+ withEvent:[NSApp currentEvent] |
+ forView:pageButton_]; |
+} |
+ |
+- (IBAction)showWrenchMenu:(id)sender { |
+ [NSMenu popUpContextMenu:wrenchMenu_ |
+ withEvent:[NSApp currentEvent] |
+ forView:wrenchButton_]; |
+} |
+ |
@end |