Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(111)

Side by Side Diff: ui/app_list/cocoa/apps_search_box_controller.mm

Issue 15955003: Menu for the OSX app launcher. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: split Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/strings/sys_string_conversions.h" 7 #include "base/strings/sys_string_conversions.h"
8 #include "ui/app_list/app_list_menu.h"
9 #import "ui/app_list/cocoa/app_list_menu_cocoa.h"
8 #include "ui/app_list/search_box_model.h" 10 #include "ui/app_list/search_box_model.h"
9 #include "ui/app_list/search_box_model_observer.h" 11 #include "ui/app_list/search_box_model_observer.h"
10 #include "ui/base/resource/resource_bundle.h" 12 #include "ui/base/resource/resource_bundle.h"
11 #include "ui/gfx/image/image_skia_util_mac.h" 13 #include "ui/gfx/image/image_skia_util_mac.h"
12 14
13 namespace { 15 namespace {
14 16
15 // Padding either side of the search icon. 17 // Padding either side of the search icon and menu button.
16 const CGFloat kPadding = 14; 18 const CGFloat kPadding = 14;
17 19
18 // Size of the search icon. 20 // Size of the search icon.
19 const CGFloat kSearchIconDimension = 32; 21 const CGFloat kSearchIconDimension = 32;
20 22
23 // Size of the menu button on the right.
24 const CGFloat kMenuButtonDimension = 29;
25
26 // Vertical offset that the menu should appear below the menu button.
27 const CGFloat kMenuOffsetFromButton = 2;
28
21 } 29 }
22 30
23 @interface AppsSearchBoxController () 31 @interface AppsSearchBoxController ()
24 32
25 - (NSImageView*)searchImage; 33 - (NSImageView*)searchImage;
26 - (void)addSubviews; 34 - (void)addSubviews;
35 - (void)menuItemSelected:(NSMenuItem*)sender;
36 - (NSMenuItem*)createMenuItemAtIndex:(int)index;
27 37
28 @end 38 @end
29 39
30 namespace app_list { 40 namespace app_list {
31 41
32 class SearchBoxModelObserverBridge : public SearchBoxModelObserver { 42 class SearchBoxModelObserverBridge : public SearchBoxModelObserver {
33 public: 43 public:
34 SearchBoxModelObserverBridge(AppsSearchBoxController* parent, 44 SearchBoxModelObserverBridge(AppsSearchBoxController* parent,
35 SearchBoxModel* model); 45 SearchBoxModel* model);
36 virtual ~SearchBoxModelObserverBridge(); 46 virtual ~SearchBoxModelObserverBridge();
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
102 return self; 112 return self;
103 } 113 }
104 114
105 - (void)clearSearch { 115 - (void)clearSearch {
106 [searchInput_ setStringValue:[NSString string]]; 116 [searchInput_ setStringValue:[NSString string]];
107 [self controlTextDidChange:nil]; 117 [self controlTextDidChange:nil];
108 } 118 }
109 119
110 - (void)setDelegate:(id<AppsSearchBoxDelegate>)delegate { 120 - (void)setDelegate:(id<AppsSearchBoxDelegate>)delegate {
111 delegate_ = delegate; 121 delegate_ = delegate;
122 app_list::AppListViewDelegate* appListDelegate = [delegate appListDelegate];
112 app_list::SearchBoxModel* searchBoxModel = [delegate searchBoxModel]; 123 app_list::SearchBoxModel* searchBoxModel = [delegate searchBoxModel];
124 appListMenu_.reset(appListDelegate ?
125 new app_list::AppListMenu(appListDelegate) : NULL);
113 bridge_.reset(searchBoxModel ? 126 bridge_.reset(searchBoxModel ?
114 new app_list::SearchBoxModelObserverBridge(self, searchBoxModel) : NULL); 127 new app_list::SearchBoxModelObserverBridge(self, searchBoxModel) : NULL);
115 } 128 }
116 129
117 - (NSTextField*)textField { 130 - (NSTextField*)textField {
118 return searchInput_; 131 return searchInput_;
119 } 132 }
120 133
134 - (NSPopUpButton*)menuControl {
135 return menuButton_;
136 }
137
138 - (app_list::AppListMenu*)appListMenu {
139 return appListMenu_.get();
140 }
141
121 - (NSImageView*)searchImage { 142 - (NSImageView*)searchImage {
122 return searchImage_; 143 return searchImage_;
123 } 144 }
124 145
125 - (void)addSubviews { 146 - (void)addSubviews {
126 NSSize viewSize = [[self view] bounds].size; 147 NSSize viewSize = [[self view] bounds].size;
127 searchImage_.reset([[NSImageView alloc] initWithFrame:NSMakeRect( 148 searchImage_.reset([[NSImageView alloc] initWithFrame:NSMakeRect(
128 kPadding, 0, kSearchIconDimension, viewSize.height)]); 149 kPadding, 0, kSearchIconDimension, viewSize.height)]);
129 150
130 searchInput_.reset([[NSTextField alloc] initWithFrame:NSZeroRect]); 151 searchInput_.reset([[NSTextField alloc] initWithFrame:NSZeroRect]);
131 [searchInput_ setFocusRingType:NSFocusRingTypeNone]; 152 [searchInput_ setFocusRingType:NSFocusRingTypeNone];
132 [searchInput_ setDrawsBackground:NO]; 153 [searchInput_ setDrawsBackground:NO];
133 [searchInput_ setBordered:NO]; 154 [searchInput_ setBordered:NO];
134 [searchInput_ setDelegate:self]; 155 [searchInput_ setDelegate:self];
135 [searchInput_ setFont:ui::ResourceBundle::GetSharedInstance().GetFont( 156 [searchInput_ setFont:ui::ResourceBundle::GetSharedInstance().GetFont(
136 ui::ResourceBundle::MediumFont).GetNativeFont()]; 157 ui::ResourceBundle::MediumFont).GetNativeFont()];
137 158
138 // Find the preferred height for those text properties, and center. 159 // Find the preferred height for those text properties, and center.
139 [searchInput_ sizeToFit]; 160 [searchInput_ sizeToFit];
140 CGFloat inputXOffset = kSearchIconDimension + 2 * kPadding; 161 CGFloat inputXOffset = kSearchIconDimension + 2 * kPadding;
141 CGFloat inputHeight = NSHeight([searchInput_ bounds]); 162 CGFloat inputHeight = NSHeight([searchInput_ bounds]);
142 [searchInput_ setFrame:NSMakeRect( 163 [searchInput_ setFrame:NSMakeRect(
143 inputXOffset, 164 inputXOffset,
144 floor(viewSize.height / 2 - inputHeight / 2), 165 floor(viewSize.height / 2 - inputHeight / 2),
145 viewSize.width - inputXOffset - kPadding, 166 viewSize.width - inputXOffset - kMenuButtonDimension - 2 * kPadding,
146 inputHeight)]; 167 inputHeight)];
147 168
169 // Add the drop-down menu, with a custom button.
170 NSRect buttonFrame = NSMakeRect(
171 NSMaxX([searchInput_ frame]) + kPadding,
172 floor(viewSize.height / 2 - kMenuButtonDimension / 2),
173 kMenuButtonDimension,
174 kMenuButtonDimension);
175 menuButton_.reset([[AppListMenuCocoa alloc] initWithFrame:buttonFrame]);
176 [[menuButton_ menu] setDelegate:self];
177
148 [[self view] addSubview:searchImage_]; 178 [[self view] addSubview:searchImage_];
149 [[self view] addSubview:searchInput_]; 179 [[self view] addSubview:searchInput_];
180 [[self view] addSubview:menuButton_];
181 }
182
183 - (void)menuItemSelected:(NSMenuItem*)sender {
184 if (!appListMenu_)
185 return;
186
187 appListMenu_->menu_model()->ActivatedAt([sender tag]);
188 }
189
190 - (void)menuNeedsUpdate:(NSMenu*)menu {
191 if (!appListMenu_)
192 return;
193
194 int itemCount = appListMenu_->menu_model()->GetItemCount();
195 if ([menu numberOfItems] == itemCount)
196 return; // Already populated.
197
198 for (int i = 0; i < itemCount; ++i)
199 [menu addItem:[self createMenuItemAtIndex:i]];
200 }
201
202 - (NSMenuItem*)createMenuItemAtIndex:(int)index {
203 DCHECK(appListMenu_);
204 ui::MenuModel* menuModel = appListMenu_->menu_model();
205 if (menuModel->GetTypeAt(index) == ui::MenuModel::TYPE_SEPARATOR)
206 return [NSMenuItem separatorItem];
207
208 string16 labelText = menuModel->GetLabelAt(index);
209 scoped_nsobject<NSMenuItem> item(
210 [[NSMenuItem alloc] initWithTitle:base::SysUTF16ToNSString(labelText)
211 action:@selector(menuItemSelected:)
212 keyEquivalent:[NSString string]]);
213 [item setTag:index];
214 [item setTarget:self];
215 if (menuModel->GetCommandIdAt(index) == app_list::AppListMenu::CURRENT_USER) {
216 [item setView:
217 [AppListMenuCocoa makeCurrentUserView:[delegate_ appListDelegate]]];
218 }
219
220 return item.autorelease();
221 }
222
223 - (NSRect)confinementRectForMenu:(NSMenu*)menu
224 onScreen:(NSScreen*)screen {
225 // Ensure the menu comes up below the menu button by trimming the window frame
226 // to a point anchored below the bottom right of the button.
227 NSPoint anchor = NSMakePoint(kMenuButtonDimension,
228 kMenuButtonDimension + kMenuOffsetFromButton);
229 anchor = [menuButton_ convertPoint:anchor
230 toView:nil];
231 anchor = [[menuButton_ window] convertBaseToScreen:anchor];
232 NSRect rect = [[menuButton_ window] frame];
233 rect.size = NSMakeSize(anchor.x - NSMinX(rect), anchor.y - NSMinY(rect));
234 return rect;
150 } 235 }
151 236
152 - (BOOL)control:(NSControl*)control 237 - (BOOL)control:(NSControl*)control
153 textView:(NSTextView*)textView 238 textView:(NSTextView*)textView
154 doCommandBySelector:(SEL)command { 239 doCommandBySelector:(SEL)command {
155 // Forward the message first, to handle grid or search results navigation. 240 // Forward the message first, to handle grid or search results navigation.
156 BOOL handled = [delegate_ control:control 241 BOOL handled = [delegate_ control:control
157 textView:textView 242 textView:textView
158 doCommandBySelector:command]; 243 doCommandBySelector:command];
159 if (handled) 244 if (handled)
160 return YES; 245 return YES;
161 246
162 // Escape when there is text clears the search input. 247 // Escape when there is text clears the search input.
163 if (command == @selector(complete:)) { 248 if (command == @selector(complete:)) {
164 [self clearSearch]; 249 [self clearSearch];
165 return YES; 250 return YES;
166 } 251 }
167 252
168 return NO; 253 return NO;
169 } 254 }
170 255
171 - (void)controlTextDidChange:(NSNotification*)notification { 256 - (void)controlTextDidChange:(NSNotification*)notification {
172 if (bridge_) 257 if (bridge_)
173 bridge_->updateModel(base::SysNSStringToUTF16([searchInput_ stringValue])); 258 bridge_->updateModel(base::SysNSStringToUTF16([searchInput_ stringValue]));
174 259
175 [delegate_ modelTextDidChange]; 260 [delegate_ modelTextDidChange];
176 } 261 }
177 262
178 @end 263 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698