| 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 #include "base/mac_util.h" |
| 5 #include "base/sys_string_conversions.h" | 6 #include "base/sys_string_conversions.h" |
| 6 #include "chrome/browser/bookmarks/bookmark_model.h" | 7 #include "chrome/browser/bookmarks/bookmark_model.h" |
| 7 #include "chrome/browser/browser.h" | 8 #include "chrome/browser/browser.h" |
| 8 #include "chrome/browser/browser_list.h" | 9 #include "chrome/browser/browser_list.h" |
| 9 #import "chrome/browser/cocoa/bookmark_bar_bridge.h" | 10 #import "chrome/browser/cocoa/bookmark_bar_bridge.h" |
| 10 #import "chrome/browser/cocoa/bookmark_bar_controller.h" | 11 #import "chrome/browser/cocoa/bookmark_bar_controller.h" |
| 11 #import "chrome/browser/cocoa/bookmark_bar_view.h" | 12 #import "chrome/browser/cocoa/bookmark_bar_view.h" |
| 12 #import "chrome/browser/cocoa/bookmark_button_cell.h" | 13 #import "chrome/browser/cocoa/bookmark_button_cell.h" |
| 13 #include "chrome/browser/profile.h" | 14 #include "chrome/browser/profile.h" |
| 14 #include "chrome/common/pref_names.h" | 15 #include "chrome/common/pref_names.h" |
| 15 #include "chrome/common/pref_service.h" | 16 #include "chrome/common/pref_service.h" |
| 16 #include "skia/ext/skia_utils_mac.h" | 17 #include "skia/ext/skia_utils_mac.h" |
| 17 | 18 |
| 18 @interface BookmarkBarController(Private) | 19 @interface BookmarkBarController(Private) |
| 19 - (void)applyContentAreaOffset:(BOOL)apply immediately:(BOOL)immediately; | 20 - (void)applyContentAreaOffset:(BOOL)apply immediately:(BOOL)immediately; |
| 20 - (void)showBookmarkBar:(BOOL)enable immediately:(BOOL)immediately; | 21 - (void)showBookmarkBar:(BOOL)enable immediately:(BOOL)immediately; |
| 21 @end | 22 @end |
| 22 | 23 |
| 23 namespace { | 24 namespace { |
| 24 | 25 |
| 26 // TODO(jrg): this is the right proportional height but overlaps the |
| 27 // "blue outline" of the omnibox. Fix. |
| 28 |
| 25 // Our height, when opened. | 29 // Our height, when opened. |
| 26 const int kBookmarkBarHeight = 30; | 30 const int kBookmarkBarHeight = 30; |
| 27 // How much to adjust our parent view. | 31 // How much to adjust our parent view. |
| 28 const int kBookmarkBarSuperviewHeightAdjustment = 25; | 32 const int kBookmarkBarSuperviewHeightAdjustment = 25; |
| 29 // How much to adjust the web frame. | 33 // How much to adjust the web frame. |
| 30 const int kBookmarkBarWebframeHeightAdjustment = 25; | 34 const int kBookmarkBarWebframeHeightAdjustment = 25; |
| 31 | 35 |
| 32 // Magic numbers from Cole | 36 // Magic numbers from Cole |
| 33 const CGFloat kDefaultBookmarkWidth = 150.0; | 37 const CGFloat kDefaultBookmarkWidth = 150.0; |
| 34 const CGFloat kBookmarkVerticalPadding = 2.0; | 38 const CGFloat kBookmarkVerticalPadding = 2.0; |
| 35 const CGFloat kBookmarkHorizontalPadding = 8.0; | 39 const CGFloat kBookmarkHorizontalPadding = 8.0; |
| 36 }; | 40 }; |
| 37 | 41 |
| 38 @implementation BookmarkBarController | 42 @implementation BookmarkBarController |
| 39 | 43 |
| 40 - (id)initWithProfile:(Profile*)profile | 44 - (id)initWithProfile:(Profile*)profile |
| 41 view:(BookmarkBarView*)view | 45 parentView:(NSView*)parentView |
| 42 webContentView:(NSView*)webContentView | 46 webContentView:(NSView*)webContentView |
| 43 delegate:(id<BookmarkURLOpener>)delegate { | 47 delegate:(id<BookmarkURLOpener>)delegate { |
| 44 if ((self = [super init])) { | 48 if ((self = [super initWithNibName:@"BookmarkBar" |
| 49 bundle:mac_util::MainAppBundle()])) { |
| 45 bookmarkModel_ = profile->GetBookmarkModel(); | 50 bookmarkModel_ = profile->GetBookmarkModel(); |
| 46 bookmarkBarView_ = view; | 51 preferences_ = profile->GetPrefs(); |
| 47 // We default to NOT open, which means height=0. | 52 parentView_ = parentView; |
| 48 DCHECK([view isHidden]); // OK to change | |
| 49 NSRect frame = [view frame]; | |
| 50 frame.size.height = 0; | |
| 51 [view setFrame:frame]; | |
| 52 | |
| 53 // Make sure the nodes stay bottom-aligned. | |
| 54 [bookmarkBarView_ setAutoresizingMask:(NSViewWidthSizable | | |
| 55 NSViewMinYMargin)]; | |
| 56 webContentView_ = webContentView; | 53 webContentView_ = webContentView; |
| 57 delegate_ = delegate; | 54 delegate_ = delegate; |
| 58 // Be sure to enable the bar before trying to show it... | |
| 59 barIsEnabled_ = YES; | |
| 60 preferences_ = profile->GetPrefs(); | |
| 61 if (preferences_->GetBoolean(prefs::kShowBookmarkBar)) | |
| 62 [self showBookmarkBar:YES immediately:YES]; | |
| 63 } | 55 } |
| 64 // Don't pass ourself along until our init is done. | 56 return self; |
| 65 // Thus, this call is (almost) last. | 57 } |
| 58 |
| 59 - (void)awakeFromNib { |
| 60 // We default to NOT open, which means height=0. |
| 61 DCHECK([[self view] isHidden]); // Hidden so it's OK to change. |
| 62 NSRect frame = [[self view] frame]; |
| 63 frame.size.height = 0; |
| 64 frame.size.width = [parentView_ frame].size.width; |
| 65 [[self view] setFrame:frame]; |
| 66 |
| 67 // Make sure the nodes stay bottom-aligned. |
| 68 [[self view] setAutoresizingMask:(NSViewWidthSizable | |
| 69 NSViewMinYMargin)]; |
| 70 // Be sure to enable the bar before trying to show it... |
| 71 barIsEnabled_ = YES; |
| 72 if (preferences_->GetBoolean(prefs::kShowBookmarkBar)) |
| 73 [self showBookmarkBar:YES immediately:YES]; |
| 74 |
| 75 // Don't pass ourself along (as 'self') until our init is completely |
| 76 // done. Thus, this call is (almost) last. |
| 66 bridge_.reset(new BookmarkBarBridge(self, bookmarkModel_)); | 77 bridge_.reset(new BookmarkBarBridge(self, bookmarkModel_)); |
| 67 return self; | |
| 68 } | 78 } |
| 69 | 79 |
| 70 // Show or hide the bar based on the value of |show|. Handles | 80 // Show or hide the bar based on the value of |show|. Handles |
| 71 // animating the resize of the content view. if |immediately| is YES, | 81 // animating the resize of the content view. if |immediately| is YES, |
| 72 // make changes immediately instead of using an animator. If the bar | 82 // make changes immediately instead of using an animator. If the bar |
| 73 // is disabled, do absolutely nothing. The routine which enables the | 83 // is disabled, do absolutely nothing. The routine which enables the |
| 74 // bar will show it if relevant using other mechanisms (the pref) to | 84 // bar will show it if relevant using other mechanisms (the pref) to |
| 75 // determine desired state. | 85 // determine desired state. |
| 76 - (void)showBookmarkBar:(BOOL)show immediately:(BOOL)immediately { | 86 - (void)showBookmarkBar:(BOOL)show immediately:(BOOL)immediately { |
| 77 if (barIsEnabled_ && (barShouldBeShown_ != show)) { | 87 if (barIsEnabled_ && (barShouldBeShown_ != show)) { |
| 78 contentViewHasOffset_ = show; | 88 contentViewHasOffset_ = show; |
| 79 [bookmarkBarView_ setHidden:show ? NO : YES]; | 89 [[self view] setHidden:show ? NO : YES]; |
| 80 barShouldBeShown_ = show; | 90 barShouldBeShown_ = show; |
| 81 if (show) { | 91 if (show) { |
| 82 [self loaded:bookmarkModel_]; | 92 [self loaded:bookmarkModel_]; |
| 83 } | 93 } |
| 84 [self applyContentAreaOffset:show immediately:immediately]; | 94 [self applyContentAreaOffset:show immediately:immediately]; |
| 85 } | 95 } |
| 86 } | 96 } |
| 87 | 97 |
| 88 // Apply a contents box offset to make (or remove) room for the | 98 // Apply a contents box offset to make (or remove) room for the |
| 89 // bookmark bar. If apply==YES, always make room (the contentView_ is | 99 // bookmark bar. If apply==YES, always make room (the contentView_ is |
| 90 // "full size"). If apply==NO we are trying to undo an offset. If no | 100 // "full size"). If apply==NO we are trying to undo an offset. If no |
| 91 // offset there is nothing to undo. | 101 // offset there is nothing to undo. |
| 92 // | 102 // |
| 93 // TODO(jrg): it is awkward we change the sizes of views for our | 103 // TODO(jrg): it is awkward we change the sizes of views for our |
| 94 // parent and siblings; ideally they change their own sizes. | 104 // parent and siblings; ideally they change their own sizes. |
| 95 // | 105 // |
| 96 // TODO(jrg): unlike windows, we process events while an animator is | 106 // TODO(jrg): unlike windows, we process events while an animator is |
| 97 // running. Thus, if you resize the window while the bookmark bar is | 107 // running. Thus, if you resize the window while the bookmark bar is |
| 98 // animating, you'll mess things up. Fix. | 108 // animating, you'll mess things up. Fix. |
| 99 - (void)applyContentAreaOffset:(BOOL)apply immediately:(BOOL)immediately { | 109 - (void)applyContentAreaOffset:(BOOL)apply immediately:(BOOL)immediately { |
| 100 if (bookmarkBarView_ == nil) { | 110 if ([self view] == nil) { |
| 101 // We're too early, but awakeFromNib will call me again. | 111 // We're too early, but awakeFromNib will call me again. |
| 102 return; | 112 return; |
| 103 } | 113 } |
| 104 if (!contentViewHasOffset_ && apply) { | 114 if (!contentViewHasOffset_ && apply) { |
| 105 // There is no offset to unconditionally apply. | 115 // There is no offset to unconditionally apply. |
| 106 return; | 116 return; |
| 107 } | 117 } |
| 108 | 118 |
| 109 // None of these locals are members of the Hall of Justice. | 119 // None of these locals are members of the Hall of Justice. |
| 110 NSView* superview = [bookmarkBarView_ superview]; | 120 NSRect superframe = [parentView_ frame]; |
| 111 NSRect superframe = [superview frame]; | 121 NSRect frame = [[self view] frame]; |
| 112 NSRect frame = [bookmarkBarView_ frame]; | |
| 113 NSRect webframe = [webContentView_ frame]; | 122 NSRect webframe = [webContentView_ frame]; |
| 114 if (apply) { | 123 if (apply) { |
| 115 superframe.size.height += kBookmarkBarSuperviewHeightAdjustment; | 124 superframe.size.height += kBookmarkBarSuperviewHeightAdjustment; |
| 116 superframe.origin.y -= kBookmarkBarSuperviewHeightAdjustment; | 125 superframe.origin.y -= kBookmarkBarSuperviewHeightAdjustment; |
| 117 frame.size.height += kBookmarkBarHeight; | 126 frame.size.height += kBookmarkBarHeight; |
| 118 webframe.size.height -= kBookmarkBarWebframeHeightAdjustment; | 127 webframe.size.height -= kBookmarkBarWebframeHeightAdjustment; |
| 119 } else { | 128 } else { |
| 120 superframe.size.height -= kBookmarkBarSuperviewHeightAdjustment; | 129 superframe.size.height -= kBookmarkBarSuperviewHeightAdjustment; |
| 121 superframe.origin.y += kBookmarkBarSuperviewHeightAdjustment; | 130 superframe.origin.y += kBookmarkBarSuperviewHeightAdjustment; |
| 122 frame.size.height -= kBookmarkBarHeight; | 131 frame.size.height -= kBookmarkBarHeight; |
| 123 webframe.size.height += kBookmarkBarWebframeHeightAdjustment; | 132 webframe.size.height += kBookmarkBarWebframeHeightAdjustment; |
| 124 } | 133 } |
| 125 | 134 |
| 126 // TODO(jrg): Animators can be a little fussy. Setting these three | 135 // TODO(jrg): Animators can be a little fussy. Setting these three |
| 127 // off can sometimes causes races where the finish isn't as | 136 // off can sometimes causes races where the finish isn't as |
| 128 // expected. Fix, or clean out the animators as an option. | 137 // expected. Fix, or clean out the animators as an option. |
| 129 // Odd racing is FAR worse than a lack of an animator. | 138 // Odd racing is FAR worse than a lack of an animator. |
| 130 if (1 /* immediately */) { | 139 if (1 /* immediately */) { |
| 131 [superview setFrame:superframe]; | 140 [parentView_ setFrame:superframe]; |
| 132 [webContentView_ setFrame:webframe]; | 141 [webContentView_ setFrame:webframe]; |
| 133 [bookmarkBarView_ setFrame:frame]; | 142 [[self view] setFrame:frame]; |
| 134 } else { | 143 } else { |
| 135 [[superview animator] setFrame:superframe]; | 144 [[parentView_ animator] setFrame:superframe]; |
| 136 [[webContentView_ animator] setFrame:webframe]; | 145 [[webContentView_ animator] setFrame:webframe]; |
| 137 [[bookmarkBarView_ animator] setFrame:frame]; | 146 [[[self view] animator] setFrame:frame]; |
| 138 } | 147 } |
| 139 | 148 |
| 140 [bookmarkBarView_ setNeedsDisplay:YES]; | 149 [[self view] setNeedsDisplay:YES]; |
| 141 [superview setNeedsDisplay:YES]; | 150 [parentView_ setNeedsDisplay:YES]; |
| 142 [webContentView_ setNeedsDisplay:YES]; | 151 [webContentView_ setNeedsDisplay:YES]; |
| 143 } | 152 } |
| 144 | 153 |
| 145 - (BOOL)isBookmarkBarVisible { | 154 - (BOOL)isBookmarkBarVisible { |
| 146 return barShouldBeShown_; | 155 return barShouldBeShown_; |
| 147 } | 156 } |
| 148 | 157 |
| 149 // We don't change a preference; we only change visibility. | 158 // We don't change a preference; we only change visibility. |
| 150 // Preference changing (global state) is handled in | 159 // Preference changing (global state) is handled in |
| 151 // BrowserWindowCocoa::ToggleBookmarkBar(). | 160 // BrowserWindowCocoa::ToggleBookmarkBar(). |
| 152 - (void)toggleBookmarkBar { | 161 - (void)toggleBookmarkBar { |
| 153 [self showBookmarkBar:!barShouldBeShown_ immediately:YES]; | 162 [self showBookmarkBar:!barShouldBeShown_ immediately:YES]; |
| 154 } | 163 } |
| 155 | 164 |
| 156 - (void)setBookmarkBarEnabled:(BOOL)enabled { | 165 - (void)setBookmarkBarEnabled:(BOOL)enabled { |
| 157 if (enabled) { | 166 if (enabled) { |
| 158 // Enabling the bar; set enabled then show if needed. | 167 // Enabling the bar; set enabled then show if needed. |
| 159 barIsEnabled_ = YES; | 168 barIsEnabled_ = YES; |
| 160 if (preferences_->GetBoolean(prefs::kShowBookmarkBar)) | 169 if (preferences_->GetBoolean(prefs::kShowBookmarkBar)) |
| 161 [self showBookmarkBar:YES immediately:YES]; | 170 [self showBookmarkBar:YES immediately:YES]; |
| 162 } else { | 171 } else { |
| 163 // Disabling the bar; hide if visible. | 172 // Disabling the bar; hide if visible. |
| 164 if ([self isBookmarkBarVisible]) { | 173 if ([self isBookmarkBarVisible]) { |
| 165 [self showBookmarkBar:NO immediately:YES]; | 174 [self showBookmarkBar:NO immediately:YES]; |
| 166 } | 175 } |
| 167 barIsEnabled_ = NO; | 176 barIsEnabled_ = NO; |
| 168 } | 177 } |
| 169 } | 178 } |
| 170 | 179 |
| 171 // Delete all items from the bookmark bar. | 180 - (BookmarkNode*)nodeFromMenuItem:(id)menuItem { |
| 172 - (void)clearBookmarkBar { | 181 NSCell* cell = [[menuItem menu] delegate]; |
| 173 [bookmarkBarView_ setSubviews:[NSArray array]]; | 182 BookmarkNode* node = static_cast<BookmarkNode*>( |
| 183 [[cell representedObject] pointerValue]); |
| 184 DCHECK(node); |
| 185 return node; |
| 174 } | 186 } |
| 175 | 187 |
| 176 // TODO(jrg): add an openBookmarkInBackground() for ctrl-click which | 188 - (BookmarkNode*)nodeFromButton:(id)button { |
| 177 // has a different disposition. | 189 NSCell* cell = [button cell]; |
| 178 - (void)openBookmark:(id)sender { | 190 BookmarkNode* node = static_cast<BookmarkNode*>( |
| 179 const BookmarkNode* node = static_cast<const BookmarkNode*>( | 191 [[cell representedObject] pointerValue]); |
| 180 [[[sender cell] representedObject] pointerValue]); | |
| 181 DCHECK(node); | 192 DCHECK(node); |
| 193 return node; |
| 194 } |
| 195 |
| 196 - (IBAction)openBookmark:(id)sender { |
| 197 BookmarkNode* node = [self nodeFromButton:sender]; |
| 182 [delegate_ openBookmarkURL:node->GetURL() disposition:CURRENT_TAB]; | 198 [delegate_ openBookmarkURL:node->GetURL() disposition:CURRENT_TAB]; |
| 183 } | 199 } |
| 184 | 200 |
| 201 // As a convention we set the menu's delegate to be the button's cell |
| 202 // so we can easily obtain bookmark info. Convention applied in |
| 203 // -[BookmarkButtonCell menu]. |
| 204 |
| 205 - (IBAction)openBookmarkInNewForegroundTab:(id)sender { |
| 206 BookmarkNode* node = [self nodeFromMenuItem:sender]; |
| 207 [delegate_ openBookmarkURL:node->GetURL() disposition:NEW_FOREGROUND_TAB]; |
| 208 } |
| 209 |
| 210 - (IBAction)openBookmarkInNewWindow:(id)sender { |
| 211 BookmarkNode* node = [self nodeFromMenuItem:sender]; |
| 212 [delegate_ openBookmarkURL:node->GetURL() disposition:NEW_WINDOW]; |
| 213 } |
| 214 |
| 215 - (IBAction)openBookmarkInIncognitoWindow:(id)sender { |
| 216 BookmarkNode* node = [self nodeFromMenuItem:sender]; |
| 217 [delegate_ openBookmarkURL:node->GetURL() disposition:OFF_THE_RECORD]; |
| 218 } |
| 219 |
| 220 - (IBAction)deleteBookmark:(id)sender { |
| 221 BookmarkNode* node = [self nodeFromMenuItem:sender]; |
| 222 bookmarkModel_->Remove(node->GetParent(), |
| 223 node->GetParent()->IndexOfChild(node)); |
| 224 } |
| 225 |
| 226 // Delete all items from the bookmark bar. TODO(jrg): once the |
| 227 // bookmark bar has other subviews (e.g. "off the side" button/menu, |
| 228 // "Other Bookmarks"), etc, this routine will need revisiting. |
| 229 - (void)clearBookmarkBar { |
| 230 [[self view] setSubviews:[NSArray array]]; |
| 231 } |
| 232 |
| 185 // Return an autoreleased NSCell suitable for a bookmark button. | 233 // Return an autoreleased NSCell suitable for a bookmark button. |
| 186 // TODO(jrg): move much of the cell config into the BookmarkButtonCell class. | 234 // TODO(jrg): move much of the cell config into the BookmarkButtonCell class. |
| 187 - (NSCell *)cellForBookmarkNode:(const BookmarkNode*)node frame:(NSRect)frame { | 235 - (NSCell *)cellForBookmarkNode:(const BookmarkNode*)node frame:(NSRect)frame { |
| 188 NSString* title = base::SysWideToNSString(node->GetTitle()); | 236 NSString* title = base::SysWideToNSString(node->GetTitle()); |
| 189 NSButtonCell *cell = [[[BookmarkButtonCell alloc] initTextCell:nil] | 237 NSButtonCell *cell = [[[BookmarkButtonCell alloc] initTextCell:nil] |
| 190 autorelease]; | 238 autorelease]; |
| 191 DCHECK(cell); | 239 DCHECK(cell); |
| 192 [cell setRepresentedObject:[NSValue valueWithPointer:node]]; | 240 [cell setRepresentedObject:[NSValue valueWithPointer:node]]; |
| 193 [cell setButtonType:NSMomentaryPushInButton]; | |
| 194 [cell setBezelStyle:NSShadowlessSquareBezelStyle]; | |
| 195 [cell setShowsBorderOnlyWhileMouseInside:YES]; | |
| 196 | 241 |
| 197 // The favicon may be NULL if we haven't loaded it yet. Bookmarks | 242 // The favicon may be NULL if we haven't loaded it yet. Bookmarks |
| 198 // (and their icons) are loaded on the IO thread to speed launch. | 243 // (and their icons) are loaded on the IO thread to speed launch. |
| 199 const SkBitmap& favicon = bookmarkModel_->GetFavIcon(node); | 244 const SkBitmap& favicon = bookmarkModel_->GetFavIcon(node); |
| 200 if (!favicon.isNull()) { | 245 if (!favicon.isNull()) { |
| 201 NSImage* image = gfx::SkBitmapToNSImage(favicon); | 246 NSImage* image = gfx::SkBitmapToNSImage(favicon); |
| 202 if (image) { | 247 if (image) { |
| 203 [cell setImage:image]; | 248 [cell setImage:image]; |
| 204 [cell setImagePosition:NSImageLeft]; | 249 [cell setImagePosition:NSImageLeft]; |
| 205 } | 250 } |
| 206 } | 251 } |
| 207 | |
| 208 [cell setTitle:title]; | 252 [cell setTitle:title]; |
| 209 [cell setControlSize:NSSmallControlSize]; | 253 [cell setMenu:buttonContextMenu_]; |
| 210 [cell setAlignment:NSLeftTextAlignment]; | |
| 211 [cell setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]]; | |
| 212 [cell setWraps:NO]; | |
| 213 [cell setLineBreakMode:NSLineBreakByTruncatingMiddle]; | |
| 214 return cell; | 254 return cell; |
| 215 } | 255 } |
| 216 | 256 |
| 217 // TODO(jrg): accomodation for bookmarks less than minimum width in | 257 // TODO(jrg): accomodation for bookmarks less than minimum width in |
| 218 // size (like Windows)? | 258 // size (like Windows)? |
| 219 - (NSRect)frameForBookmarkAtIndex:(int)index { | 259 - (NSRect)frameForBookmarkAtIndex:(int)index { |
| 220 NSRect bounds = [[self view] bounds]; | 260 NSRect bounds = [[self view] bounds]; |
| 221 // TODO: be smarter about this; the animator delays the right height | 261 // TODO: be smarter about this; the animator delays the right height |
| 222 if (bounds.size.height == 0) | 262 if (bounds.size.height == 0) |
| 223 bounds.size.height = kBookmarkBarHeight; | 263 bounds.size.height = kBookmarkBarHeight; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 250 NSRect frame = [self frameForBookmarkAtIndex:i]; | 290 NSRect frame = [self frameForBookmarkAtIndex:i]; |
| 251 NSButton* button = [[[NSButton alloc] initWithFrame:frame] | 291 NSButton* button = [[[NSButton alloc] initWithFrame:frame] |
| 252 autorelease]; | 292 autorelease]; |
| 253 DCHECK(button); | 293 DCHECK(button); |
| 254 // [NSButton setCell:] warns to NOT use setCell: other than in the | 294 // [NSButton setCell:] warns to NOT use setCell: other than in the |
| 255 // initializer of a control. However, we are using a basic | 295 // initializer of a control. However, we are using a basic |
| 256 // NSButton whose initializer does not take an NSCell as an | 296 // NSButton whose initializer does not take an NSCell as an |
| 257 // object. To honor the assumed semantics, we do nothing with | 297 // object. To honor the assumed semantics, we do nothing with |
| 258 // NSButton between alloc/init and setCell:. | 298 // NSButton between alloc/init and setCell:. |
| 259 [button setCell:[self cellForBookmarkNode:child frame:frame]]; | 299 [button setCell:[self cellForBookmarkNode:child frame:frame]]; |
| 260 // [button sizeToFit]; | |
| 261 | 300 |
| 262 if (child->is_folder()) { | 301 if (child->is_folder()) { |
| 263 // For now just disable the button if it's a folder. | 302 // For now just disable the button if it's a folder. |
| 264 // TODO(jrg): recurse. | 303 // TODO(jrg): recurse. |
| 265 [button setEnabled:NO]; | 304 [button setEnabled:NO]; |
| 266 } else { | 305 } else { |
| 267 // Make the button do something | 306 // Make the button do something |
| 268 [button setTarget:self]; | 307 [button setTarget:self]; |
| 269 [button setAction:@selector(openBookmark:)]; | 308 [button setAction:@selector(openBookmark:)]; |
| 270 // Add a tooltip. | 309 // Add a tooltip. |
| 271 NSString* title = base::SysWideToNSString(child->GetTitle()); | 310 NSString* title = base::SysWideToNSString(child->GetTitle()); |
| 272 std::string url_string = child->GetURL().possibly_invalid_spec(); | 311 std::string url_string = child->GetURL().possibly_invalid_spec(); |
| 273 NSString* tooltip = [NSString stringWithFormat:@"%@\n%s", title, | 312 NSString* tooltip = [NSString stringWithFormat:@"%@\n%s", title, |
| 274 url_string.c_str()]; | 313 url_string.c_str()]; |
| 275 [button setToolTip:tooltip]; | 314 [button setToolTip:tooltip]; |
| 276 } | 315 } |
| 277 // Finally, add it to the bookmark bar. | 316 // Finally, add it to the bookmark bar. |
| 278 [bookmarkBarView_ addSubview:button]; | 317 [[self view] addSubview:button]; |
| 279 } | 318 } |
| 280 } | 319 } |
| 281 | 320 |
| 282 // TODO(jrg): for now this is brute force. | 321 // TODO(jrg): for now this is brute force. |
| 283 - (void)loaded:(BookmarkModel*)model { | 322 - (void)loaded:(BookmarkModel*)model { |
| 284 DCHECK(model == bookmarkModel_); | 323 DCHECK(model == bookmarkModel_); |
| 285 // Do nothing if not active or too early | 324 // Do nothing if not active or too early |
| 286 if ((barShouldBeShown_ == NO) || !model->IsLoaded()) | 325 if ((barShouldBeShown_ == NO) || !model->IsLoaded()) |
| 287 return; | 326 return; |
| 288 // Else brute force nuke and build. | 327 // Else brute force nuke and build. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 302 [self loaded:model]; | 341 [self loaded:model]; |
| 303 } | 342 } |
| 304 | 343 |
| 305 // TODO(jrg): for now this is brute force. | 344 // TODO(jrg): for now this is brute force. |
| 306 - (void)nodeAdded:(BookmarkModel*)model | 345 - (void)nodeAdded:(BookmarkModel*)model |
| 307 parent:(const BookmarkNode*)oldParent index:(int)index { | 346 parent:(const BookmarkNode*)oldParent index:(int)index { |
| 308 [self loaded:model]; | 347 [self loaded:model]; |
| 309 } | 348 } |
| 310 | 349 |
| 311 // TODO(jrg): for now this is brute force. | 350 // TODO(jrg): for now this is brute force. |
| 351 - (void)nodeRemoved:(BookmarkModel*)model |
| 352 parent:(const BookmarkNode*)oldParent index:(int)index { |
| 353 [self loaded:model]; |
| 354 } |
| 355 |
| 356 // TODO(jrg): for now this is brute force. |
| 312 - (void)nodeChanged:(BookmarkModel*)model | 357 - (void)nodeChanged:(BookmarkModel*)model |
| 313 node:(const BookmarkNode*)node { | 358 node:(const BookmarkNode*)node { |
| 314 [self loaded:model]; | 359 [self loaded:model]; |
| 315 } | 360 } |
| 316 | 361 |
| 317 // TODO(jrg): linear searching is bad. | 362 // TODO(jrg): linear searching is bad. |
| 318 // Need a BookmarkNode-->NSCell mapping. | 363 // Need a BookmarkNode-->NSCell mapping. |
| 319 - (void)nodeFavIconLoaded:(BookmarkModel*)model | 364 - (void)nodeFavIconLoaded:(BookmarkModel*)model |
| 320 node:(const BookmarkNode*)node { | 365 node:(const BookmarkNode*)node { |
| 321 NSArray* views = [bookmarkBarView_ subviews]; | 366 NSArray* views = [[self view] subviews]; |
| 322 for (NSButton* button in views) { | 367 for (NSButton* button in views) { |
| 323 NSButtonCell* cell = [button cell]; | 368 NSButtonCell* cell = [button cell]; |
| 324 void* pointer = [[cell representedObject] pointerValue]; | 369 void* pointer = [[cell representedObject] pointerValue]; |
| 325 const BookmarkNode* cellnode = static_cast<const BookmarkNode*>(pointer); | 370 const BookmarkNode* cellnode = static_cast<const BookmarkNode*>(pointer); |
| 326 if (cellnode == node) { | 371 if (cellnode == node) { |
| 327 NSImage* image = gfx::SkBitmapToNSImage(bookmarkModel_->GetFavIcon(node)); | 372 NSImage* image = gfx::SkBitmapToNSImage(bookmarkModel_->GetFavIcon(node)); |
| 328 if (image) { | 373 if (image) { |
| 329 [cell setImage:image]; | 374 [cell setImage:image]; |
| 330 [cell setImagePosition:NSImageLeft]; | 375 [cell setImagePosition:NSImageLeft]; |
| 331 } | 376 } |
| 332 return; | 377 return; |
| 333 } | 378 } |
| 334 } | 379 } |
| 335 } | 380 } |
| 336 | 381 |
| 337 // TODO(jrg): for now this is brute force. | 382 // TODO(jrg): for now this is brute force. |
| 338 - (void)nodeChildrenReordered:(BookmarkModel*)model | 383 - (void)nodeChildrenReordered:(BookmarkModel*)model |
| 339 node:(const BookmarkNode*)node { | 384 node:(const BookmarkNode*)node { |
| 340 [self loaded:model]; | 385 [self loaded:model]; |
| 341 } | 386 } |
| 342 | 387 |
| 343 - (NSView*)view { | |
| 344 return bookmarkBarView_; | |
| 345 } | |
| 346 | |
| 347 - (void)setDelegate:(id<BookmarkURLOpener>)delegate { | 388 - (void)setDelegate:(id<BookmarkURLOpener>)delegate { |
| 348 delegate_ = delegate; | 389 delegate_ = delegate; |
| 349 } | 390 } |
| 350 | 391 |
| 351 @end | 392 @end |
| OLD | NEW |