Index: ui/app_list/cocoa/apps_search_box_controller.mm |
diff --git a/ui/app_list/cocoa/apps_search_box_controller.mm b/ui/app_list/cocoa/apps_search_box_controller.mm |
index aa0c65265a8f081b25d9aa216406549f1630312f..b28c5d4ebc514d603b9147418c7cf13f0ec61edd 100644 |
--- a/ui/app_list/cocoa/apps_search_box_controller.mm |
+++ b/ui/app_list/cocoa/apps_search_box_controller.mm |
@@ -5,6 +5,8 @@ |
#import "ui/app_list/cocoa/apps_search_box_controller.h" |
#include "base/strings/sys_string_conversions.h" |
+#include "ui/app_list/app_list_menu.h" |
+#import "ui/app_list/cocoa/app_list_menu_cocoa.h" |
#include "ui/app_list/search_box_model.h" |
#include "ui/app_list/search_box_model_observer.h" |
#include "ui/base/resource/resource_bundle.h" |
@@ -12,18 +14,26 @@ |
namespace { |
-// Padding either side of the search icon. |
+// Padding either side of the search icon and menu button. |
const CGFloat kPadding = 14; |
// Size of the search icon. |
const CGFloat kSearchIconDimension = 32; |
+// Size of the menu button on the right. |
+const CGFloat kMenuButtonDimension = 29; |
+ |
+// Vertical offset that the menu should appear below the menu button. |
+const CGFloat kMenuOffsetFromButton = 2; |
+ |
} |
@interface AppsSearchBoxController () |
- (NSImageView*)searchImage; |
- (void)addSubviews; |
+- (void)menuItemSelected:(NSMenuItem*)sender; |
+- (NSMenuItem*)createMenuItemAtIndex:(int)index; |
@end |
@@ -109,7 +119,10 @@ void SearchBoxModelObserverBridge::TextChanged() { |
- (void)setDelegate:(id<AppsSearchBoxDelegate>)delegate { |
delegate_ = delegate; |
+ app_list::AppListViewDelegate* appListDelegate = [delegate appListDelegate]; |
app_list::SearchBoxModel* searchBoxModel = [delegate searchBoxModel]; |
+ appListMenu_.reset(appListDelegate ? |
+ new app_list::AppListMenu(appListDelegate) : NULL); |
bridge_.reset(searchBoxModel ? |
new app_list::SearchBoxModelObserverBridge(self, searchBoxModel) : NULL); |
} |
@@ -118,6 +131,14 @@ void SearchBoxModelObserverBridge::TextChanged() { |
return searchInput_; |
} |
+- (NSPopUpButton*)menuControl { |
+ return menuButton_; |
+} |
+ |
+- (app_list::AppListMenu*)appListMenu { |
+ return appListMenu_.get(); |
+} |
+ |
- (NSImageView*)searchImage { |
return searchImage_; |
} |
@@ -142,11 +163,75 @@ void SearchBoxModelObserverBridge::TextChanged() { |
[searchInput_ setFrame:NSMakeRect( |
inputXOffset, |
floor(viewSize.height / 2 - inputHeight / 2), |
- viewSize.width - inputXOffset - kPadding, |
+ viewSize.width - inputXOffset - kMenuButtonDimension - 2 * kPadding, |
inputHeight)]; |
+ // Add the drop-down menu, with a custom button. |
+ NSRect buttonFrame = NSMakeRect( |
+ NSMaxX([searchInput_ frame]) + kPadding, |
+ floor(viewSize.height / 2 - kMenuButtonDimension / 2), |
+ kMenuButtonDimension, |
+ kMenuButtonDimension); |
+ menuButton_.reset([[AppListMenuCocoa alloc] initWithFrame:buttonFrame]); |
+ [[menuButton_ menu] setDelegate:self]; |
+ |
[[self view] addSubview:searchImage_]; |
[[self view] addSubview:searchInput_]; |
+ [[self view] addSubview:menuButton_]; |
+} |
+ |
+- (void)menuItemSelected:(NSMenuItem*)sender { |
+ if (!appListMenu_) |
+ return; |
+ |
+ appListMenu_->menu_model()->ActivatedAt([sender tag]); |
+} |
+ |
+- (void)menuNeedsUpdate:(NSMenu*)menu { |
+ if (!appListMenu_) |
+ return; |
+ |
+ int itemCount = appListMenu_->menu_model()->GetItemCount(); |
+ if ([menu numberOfItems] == itemCount) |
+ return; // Already populated. |
+ |
+ for (int i = 0; i < itemCount; ++i) |
+ [menu addItem:[self createMenuItemAtIndex:i]]; |
+} |
+ |
+- (NSMenuItem*)createMenuItemAtIndex:(int)index { |
+ DCHECK(appListMenu_); |
+ ui::MenuModel* menuModel = appListMenu_->menu_model(); |
+ if (menuModel->GetTypeAt(index) == ui::MenuModel::TYPE_SEPARATOR) |
+ return [NSMenuItem separatorItem]; |
+ |
+ string16 labelText = menuModel->GetLabelAt(index); |
+ scoped_nsobject<NSMenuItem> item( |
+ [[NSMenuItem alloc] initWithTitle:base::SysUTF16ToNSString(labelText) |
+ action:@selector(menuItemSelected:) |
+ keyEquivalent:[NSString string]]); |
+ [item setTag:index]; |
+ [item setTarget:self]; |
+ if (menuModel->GetCommandIdAt(index) == app_list::AppListMenu::CURRENT_USER) { |
+ [item setView: |
+ [AppListMenuCocoa makeCurrentUserView:[delegate_ appListDelegate]]]; |
+ } |
+ |
+ return item.autorelease(); |
+} |
+ |
+- (NSRect)confinementRectForMenu:(NSMenu*)menu |
+ onScreen:(NSScreen*)screen { |
+ // Ensure the menu comes up below the menu button by trimming the window frame |
+ // to a point anchored below the bottom right of the button. |
+ NSPoint anchor = NSMakePoint(kMenuButtonDimension, |
+ kMenuButtonDimension + kMenuOffsetFromButton); |
+ anchor = [menuButton_ convertPoint:anchor |
+ toView:nil]; |
+ anchor = [[menuButton_ window] convertBaseToScreen:anchor]; |
+ NSRect rect = [[menuButton_ window] frame]; |
+ rect.size = NSMakeSize(anchor.x - NSMinX(rect), anchor.y - NSMinY(rect)); |
+ return rect; |
} |
- (BOOL)control:(NSControl*)control |