Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 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 "ui/app_list/cocoa/apps_search_box_controller.h" | 5 #import "ui/app_list/cocoa/apps_search_box_controller.h" |
| 6 | 6 |
| 7 #include "base/mac/foundation_util.h" | 7 #include "base/mac/foundation_util.h" |
| 8 #include "base/strings/sys_string_conversions.h" | 8 #include "base/strings/sys_string_conversions.h" |
| 9 #include "grit/ui_resources.h" | |
| 9 #import "third_party/GTM/AppKit/GTMNSBezierPath+RoundRect.h" | 10 #import "third_party/GTM/AppKit/GTMNSBezierPath+RoundRect.h" |
| 11 #include "ui/app_list/app_list_menu.h" | |
| 12 #import "ui/app_list/cocoa/current_user_menu_item_view.h" | |
| 10 #include "ui/app_list/search_box_model.h" | 13 #include "ui/app_list/search_box_model.h" |
| 11 #include "ui/app_list/search_box_model_observer.h" | 14 #include "ui/app_list/search_box_model_observer.h" |
| 15 #import "ui/base/cocoa/controls/hover_image_menu_button.h" | |
| 16 #import "ui/base/cocoa/controls/hover_image_menu_button_cell.h" | |
| 17 #import "ui/base/cocoa/menu_controller.h" | |
| 12 #include "ui/base/resource/resource_bundle.h" | 18 #include "ui/base/resource/resource_bundle.h" |
| 13 #include "ui/gfx/image/image_skia_util_mac.h" | 19 #include "ui/gfx/image/image_skia_util_mac.h" |
| 14 | 20 |
| 15 namespace { | 21 namespace { |
| 16 | 22 |
| 17 // Padding either side of the search icon. | 23 // Padding either side of the search icon and menu button. |
| 18 const CGFloat kPadding = 14; | 24 const CGFloat kPadding = 14; |
| 19 | 25 |
| 20 // Size of the search icon. | 26 // Size of the search icon. |
| 21 const CGFloat kSearchIconDimension = 32; | 27 const CGFloat kSearchIconDimension = 32; |
| 22 | 28 |
| 29 // Size of the menu button on the right. | |
| 30 const CGFloat kMenuButtonDimension = 29; | |
| 31 | |
| 32 // Vertical offset that the menu should appear below the menu button. | |
| 33 const CGFloat kMenuOffsetFromButton = 2; | |
| 34 | |
| 23 } | 35 } |
| 24 | 36 |
| 25 @interface AppsSearchBoxController () | 37 @interface AppsSearchBoxController () |
| 26 | 38 |
| 27 - (NSImageView*)searchImageView; | 39 - (NSImageView*)searchImageView; |
| 28 - (void)addSubviews; | 40 - (void)addSubviews; |
| 29 | 41 |
| 30 @end | 42 @end |
| 31 | 43 |
| 32 namespace app_list { | 44 namespace app_list { |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 105 NSRect textFrameInset_; | 117 NSRect textFrameInset_; |
| 106 } | 118 } |
| 107 | 119 |
| 108 @property(readonly, nonatomic) NSRect textFrameInset; | 120 @property(readonly, nonatomic) NSRect textFrameInset; |
| 109 | 121 |
| 110 - (void)setMarginsWithLeftMargin:(CGFloat)leftMargin | 122 - (void)setMarginsWithLeftMargin:(CGFloat)leftMargin |
| 111 rightMargin:(CGFloat)rightMargin; | 123 rightMargin:(CGFloat)rightMargin; |
| 112 | 124 |
| 113 @end | 125 @end |
| 114 | 126 |
| 127 @interface AppListMenuController : MenuController { | |
| 128 @private | |
| 129 AppsSearchBoxController* searchBoxController_; // Weak. Owns us. | |
| 130 } | |
| 131 | |
| 132 - (id)initWithSearchBoxController:(AppsSearchBoxController*)parent; | |
| 133 | |
| 134 @end | |
| 135 | |
| 115 @implementation AppsSearchBoxController | 136 @implementation AppsSearchBoxController |
| 116 | 137 |
| 117 @synthesize delegate = delegate_; | 138 @synthesize delegate = delegate_; |
| 118 | 139 |
| 119 - (id)initWithFrame:(NSRect)frame { | 140 - (id)initWithFrame:(NSRect)frame { |
| 120 if ((self = [super init])) { | 141 if ((self = [super init])) { |
| 121 scoped_nsobject<NSView> containerView([[NSView alloc] initWithFrame:frame]); | 142 scoped_nsobject<NSView> containerView([[NSView alloc] initWithFrame:frame]); |
| 122 [self setView:containerView]; | 143 [self setView:containerView]; |
| 123 [self addSubviews]; | 144 [self addSubviews]; |
| 124 } | 145 } |
| 125 return self; | 146 return self; |
| 126 } | 147 } |
| 127 | 148 |
| 128 - (void)clearSearch { | 149 - (void)clearSearch { |
| 129 [searchTextField_ setStringValue:@""]; | 150 [searchTextField_ setStringValue:@""]; |
| 130 [self controlTextDidChange:nil]; | 151 [self controlTextDidChange:nil]; |
| 131 } | 152 } |
| 132 | 153 |
| 133 - (void)setDelegate:(id<AppsSearchBoxDelegate>)delegate { | 154 - (void)setDelegate:(id<AppsSearchBoxDelegate>)delegate { |
| 155 [[menuButton_ menu] removeAllItems]; | |
| 156 menuController_.reset(); | |
| 157 appListMenu_.reset(); | |
| 134 bridge_.reset(); // Ensure observers are cleared before updating |delegate_|. | 158 bridge_.reset(); // Ensure observers are cleared before updating |delegate_|. |
| 135 delegate_ = delegate; | 159 delegate_ = delegate; |
| 136 if (!delegate_) | 160 if (!delegate_) |
| 137 return; | 161 return; |
| 138 | 162 |
| 139 bridge_.reset(new app_list::SearchBoxModelObserverBridge(self)); | 163 bridge_.reset(new app_list::SearchBoxModelObserverBridge(self)); |
| 164 if (![delegate_ appListDelegate]) | |
| 165 return; | |
| 166 | |
| 167 appListMenu_.reset(new app_list::AppListMenu([delegate_ appListDelegate])); | |
| 168 menuController_.reset([[AppListMenuController alloc] | |
| 169 initWithSearchBoxController:self]); | |
| 170 [menuButton_ setMenu:[menuController_ menu]]; // Menu will populate here. | |
| 140 } | 171 } |
| 141 | 172 |
| 142 - (NSTextField*)searchTextField { | 173 - (NSTextField*)searchTextField { |
| 143 return searchTextField_; | 174 return searchTextField_; |
| 144 } | 175 } |
| 145 | 176 |
| 177 - (NSPopUpButton*)menuControl { | |
| 178 return menuButton_; | |
| 179 } | |
| 180 | |
| 181 - (app_list::AppListMenu*)appListMenu { | |
| 182 return appListMenu_.get(); | |
| 183 } | |
| 184 | |
| 146 - (NSImageView*)searchImageView { | 185 - (NSImageView*)searchImageView { |
| 147 return searchImageView_; | 186 return searchImageView_; |
| 148 } | 187 } |
| 149 | 188 |
| 150 - (void)addSubviews { | 189 - (void)addSubviews { |
| 151 NSRect viewBounds = [[self view] bounds]; | 190 NSRect viewBounds = [[self view] bounds]; |
| 152 searchImageView_.reset([[NSImageView alloc] initWithFrame:NSMakeRect( | 191 searchImageView_.reset([[NSImageView alloc] initWithFrame:NSMakeRect( |
| 153 kPadding, 0, kSearchIconDimension, NSHeight(viewBounds))]); | 192 kPadding, 0, kSearchIconDimension, NSHeight(viewBounds))]); |
| 154 | 193 |
| 155 searchTextField_.reset([[SearchTextField alloc] initWithFrame:viewBounds]); | 194 searchTextField_.reset([[SearchTextField alloc] initWithFrame:viewBounds]); |
| 195 ui::ResourceBundle& resourceBundle = ui::ResourceBundle::GetSharedInstance(); | |
| 156 [searchTextField_ setDelegate:self]; | 196 [searchTextField_ setDelegate:self]; |
| 157 [searchTextField_ setFont:ui::ResourceBundle::GetSharedInstance().GetFont( | 197 [searchTextField_ setFont:resourceBundle.GetFont( |
| 158 ui::ResourceBundle::MediumFont).GetNativeFont()]; | 198 ui::ResourceBundle::MediumFont).GetNativeFont()]; |
| 159 [searchTextField_ | 199 [searchTextField_ |
| 160 setMarginsWithLeftMargin:NSMaxX([searchImageView_ frame]) + kPadding | 200 setMarginsWithLeftMargin:NSMaxX([searchImageView_ frame]) + kPadding |
| 161 rightMargin:kPadding]; | 201 rightMargin:kMenuButtonDimension + 2 * kPadding]; |
| 202 | |
| 203 // Add the drop-down menu, with a custom button. | |
| 204 NSRect buttonFrame = NSMakeRect( | |
| 205 NSWidth(viewBounds) - kMenuButtonDimension - kPadding, | |
| 206 floor(NSMidY(viewBounds) - kMenuButtonDimension / 2), | |
| 207 kMenuButtonDimension, | |
| 208 kMenuButtonDimension); | |
| 209 menuButton_.reset([[HoverImageMenuButton alloc] initWithFrame:buttonFrame | |
| 210 pullsDown:YES]); | |
| 211 [[menuButton_ hoverImageMenuButtonCell] setImage:resourceBundle. | |
| 212 GetNativeImageNamed(IDR_APP_LIST_TOOLS_NORMAL).AsNSImage()]; | |
| 213 [[menuButton_ hoverImageMenuButtonCell] setAlternateImage:resourceBundle. | |
| 214 GetNativeImageNamed(IDR_APP_LIST_TOOLS_PRESSED).AsNSImage()]; | |
| 215 [[menuButton_ hoverImageMenuButtonCell] setHoverImage:resourceBundle. | |
| 216 GetNativeImageNamed(IDR_APP_LIST_TOOLS_HOVER).AsNSImage()]; | |
| 162 | 217 |
| 163 [[self view] addSubview:searchImageView_]; | 218 [[self view] addSubview:searchImageView_]; |
| 164 [[self view] addSubview:searchTextField_]; | 219 [[self view] addSubview:searchTextField_]; |
| 220 [[self view] addSubview:menuButton_]; | |
| 165 } | 221 } |
| 166 | 222 |
| 167 - (BOOL)control:(NSControl*)control | 223 - (BOOL)control:(NSControl*)control |
| 168 textView:(NSTextView*)textView | 224 textView:(NSTextView*)textView |
| 169 doCommandBySelector:(SEL)command { | 225 doCommandBySelector:(SEL)command { |
| 170 // Forward the message first, to handle grid or search results navigation. | 226 // Forward the message first, to handle grid or search results navigation. |
| 171 BOOL handled = [delegate_ control:control | 227 BOOL handled = [delegate_ control:control |
| 172 textView:textView | 228 textView:textView |
| 173 doCommandBySelector:command]; | 229 doCommandBySelector:command]; |
| 174 if (handled) | 230 if (handled) |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 284 length:(NSInteger)length { | 340 length:(NSInteger)length { |
| 285 [super selectWithFrame:[self textFrameForFrame:cellFrame] | 341 [super selectWithFrame:[self textFrameForFrame:cellFrame] |
| 286 inView:controlView | 342 inView:controlView |
| 287 editor:editor | 343 editor:editor |
| 288 delegate:delegate | 344 delegate:delegate |
| 289 start:start | 345 start:start |
| 290 length:length]; | 346 length:length]; |
| 291 } | 347 } |
| 292 | 348 |
| 293 @end | 349 @end |
| 350 | |
| 351 @implementation AppListMenuController | |
| 352 | |
| 353 - (id)initWithSearchBoxController:(AppsSearchBoxController*)parent { | |
| 354 // Need to initialze super with a NULL model, otherwise it will immediately | |
| 355 // try to populate, which can't be done until setting the parent. | |
| 356 if ((self = [super initWithModel:NULL | |
| 357 useWithPopUpButtonCell:YES])) { | |
| 358 searchBoxController_ = parent; | |
| 359 [super setModel:[parent appListMenu]->menu_model()]; | |
| 360 } | |
| 361 return self; | |
| 362 } | |
| 363 | |
| 364 - (void)addItemToMenu:(NSMenu*)menu | |
| 365 atIndex:(NSInteger)index | |
| 366 fromModel:(ui::MenuModel*)model { | |
| 367 [super addItemToMenu:menu | |
| 368 atIndex:index | |
| 369 fromModel:model]; | |
| 370 if (model->GetCommandIdAt(index) != app_list::AppListMenu::CURRENT_USER) | |
| 371 return; | |
| 372 | |
| 373 scoped_nsobject<NSView> customItemView([[CurrentUserMenuItemView alloc] | |
| 374 initWithDelegate:[[searchBoxController_ delegate] appListDelegate]]); | |
| 375 [[menu itemAtIndex:index] setView:customItemView]; | |
| 376 } | |
| 377 | |
| 378 - (NSRect)confinementRectForMenu:(NSMenu*)menu | |
| 379 onScreen:(NSScreen*)screen { | |
| 380 NSPopUpButton* menuButton = [searchBoxController_ menuControl]; | |
| 381 // Ensure the menu comes up below the menu button by trimming the window frame | |
| 382 // to a point anchored below the bottom right of the button. | |
| 383 NSRect anchorRect = [menuButton convertRect:[menuButton bounds] | |
| 384 toView:nil]; | |
| 385 NSPoint anchorPoint = [[menuButton window] convertBaseToScreen:NSMakePoint( | |
|
sail
2013/06/11 00:55:22
convertBaseToScreen is deprecated
tapted
2013/06/11 02:32:44
I know... but convertRectToScreen is not available
sail
2013/06/11 18:01:24
Actually this looks ok. We do this everywhere else
| |
| 386 NSMaxX(anchorRect), | |
| 387 NSMinY(anchorRect) - kMenuOffsetFromButton)]; | |
| 388 NSRect confinementRect = [[menuButton window] frame]; | |
| 389 confinementRect.size = NSMakeSize(anchorPoint.x - NSMinX(confinementRect), | |
| 390 anchorPoint.y - NSMinY(confinementRect)); | |
| 391 return confinementRect; | |
| 392 } | |
| 393 | |
| 394 @end | |
| OLD | NEW |