OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 "chrome/browser/cocoa/autocomplete_text_field_cell.h" | 5 #import "chrome/browser/cocoa/autocomplete_text_field_cell.h" |
6 | 6 |
7 #include "app/gfx/font.h" | 7 #include "app/gfx/font.h" |
8 #include "app/resource_bundle.h" | 8 #include "app/resource_bundle.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #import "chrome/browser/cocoa/GTMTheme.h" | 10 #import "chrome/browser/cocoa/GTMTheme.h" |
11 | 11 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
50 CGFloat WidthForHint(NSAttributedString* hintString) { | 50 CGFloat WidthForHint(NSAttributedString* hintString) { |
51 return kHintXOffset + ceil([hintString size].width); | 51 return kHintXOffset + ceil([hintString size].width); |
52 } | 52 } |
53 CGFloat WidthForKeyword(NSAttributedString* keywordString) { | 53 CGFloat WidthForKeyword(NSAttributedString* keywordString) { |
54 return kKeywordXOffset + ceil([keywordString size].width) + | 54 return kKeywordXOffset + ceil([keywordString size].width) + |
55 2 * kKeywordTokenInset; | 55 2 * kKeywordTokenInset; |
56 } | 56 } |
57 | 57 |
58 } // namespace | 58 } // namespace |
59 | 59 |
| 60 @implementation AutocompleteTextFieldIcon |
| 61 |
| 62 @synthesize rect = rect_; |
| 63 @synthesize view = view_; |
| 64 |
| 65 + (AutocompleteTextFieldIcon*) |
| 66 iconWithRect:(NSRect)rect |
| 67 view:(LocationBarViewMac::LocationBarImageView*)view { |
| 68 AutocompleteTextFieldIcon* result = [[AutocompleteTextFieldIcon alloc] init]; |
| 69 [result setRect:rect]; |
| 70 [result setView:view]; |
| 71 return [result autorelease]; |
| 72 } |
| 73 |
| 74 @end |
| 75 |
60 @implementation AutocompleteTextFieldCell | 76 @implementation AutocompleteTextFieldCell |
61 | 77 |
62 // @synthesize doesn't seem to compile for this transition. | 78 // @synthesize doesn't seem to compile for this transition. |
63 - (NSAttributedString*)keywordString { | 79 - (NSAttributedString*)keywordString { |
64 return keywordString_.get(); | 80 return keywordString_.get(); |
65 } | 81 } |
66 - (NSAttributedString*)hintString { | 82 - (NSAttributedString*)hintString { |
67 return hintString_.get(); | 83 return hintString_.get(); |
68 } | 84 } |
69 | 85 |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
195 } | 211 } |
196 | 212 |
197 - (void)setPageActionViewList:(LocationBarViewMac::PageActionViewList*)list { | 213 - (void)setPageActionViewList:(LocationBarViewMac::PageActionViewList*)list { |
198 page_action_views_ = list; | 214 page_action_views_ = list; |
199 } | 215 } |
200 | 216 |
201 - (void)setSecurityImageView:(LocationBarViewMac::SecurityImageView*)view { | 217 - (void)setSecurityImageView:(LocationBarViewMac::SecurityImageView*)view { |
202 security_image_view_ = view; | 218 security_image_view_ = view; |
203 } | 219 } |
204 | 220 |
205 - (void)onSecurityIconMousePressed { | 221 - (void)setContentBlockedViewList: |
206 security_image_view_->OnMousePressed(); | 222 (LocationBarViewMac::ContentBlockedViews*)views { |
207 } | 223 content_blocked_views_ = views; |
208 | |
209 - (void)onPageActionMousePressedIn:(NSRect)iconFrame forIndex:(size_t)index { | |
210 page_action_views_->OnMousePressed(iconFrame, index); | |
211 } | 224 } |
212 | 225 |
213 // Overriden to account for the hint strings and hint icons. | 226 // Overriden to account for the hint strings and hint icons. |
214 - (NSRect)textFrameForFrame:(NSRect)cellFrame { | 227 - (NSRect)textFrameForFrame:(NSRect)cellFrame { |
215 NSRect textFrame([super textFrameForFrame:cellFrame]); | 228 NSRect textFrame([super textFrameForFrame:cellFrame]); |
216 | 229 |
217 if (hintString_) { | 230 if (hintString_) { |
218 DCHECK(!keywordString_); | 231 DCHECK(!keywordString_); |
219 const CGFloat hintWidth(WidthForHint(hintString_)); | 232 const CGFloat hintWidth(WidthForHint(hintString_)); |
220 | 233 |
221 // TODO(shess): This could be better. Show the hint until the | 234 // TODO(shess): This could be better. Show the hint until the |
222 // non-hint text bumps against it? | 235 // non-hint text bumps against it? |
223 if (hintWidth < NSWidth(cellFrame)) { | 236 if (hintWidth < NSWidth(cellFrame)) { |
224 textFrame.size.width -= hintWidth; | 237 textFrame.size.width -= hintWidth; |
225 } | 238 } |
226 } else if (keywordString_) { | 239 } else if (keywordString_) { |
227 DCHECK(!hintString_); | 240 DCHECK(!hintString_); |
228 const CGFloat keywordWidth(WidthForKeyword(keywordString_)); | 241 const CGFloat keywordWidth(WidthForKeyword(keywordString_)); |
229 | 242 |
230 // TODO(shess): This could be better. There's support for a | 243 // TODO(shess): This could be better. There's support for a |
231 // "short" version of the keyword string, work that in in a | 244 // "short" version of the keyword string, work that in in a |
232 // follow-on pass. | 245 // follow-on pass. |
233 if (keywordWidth < NSWidth(cellFrame)) { | 246 if (keywordWidth < NSWidth(cellFrame)) { |
234 textFrame.origin.x += keywordWidth; | 247 textFrame.origin.x += keywordWidth; |
235 textFrame.size.width = NSMaxX(cellFrame) - NSMinX(textFrame); | 248 textFrame.size.width = NSMaxX(cellFrame) - NSMinX(textFrame); |
236 } | 249 } |
237 } else { | 250 } else { |
238 // Account for the lock icon, if any, and any visible Page Action icons. | 251 // Leave room for images on the right (lock icon etc). |
| 252 NSArray* iconFrames = [self layedOutIcons:cellFrame]; |
239 CGFloat width = 0; | 253 CGFloat width = 0; |
240 const size_t iconCount = [self pageActionCount]; | 254 if ([iconFrames count] > 0) |
241 for (size_t i = 0; i < iconCount; ++i) { | 255 width = NSMaxX(cellFrame) - NSMinX([[iconFrames lastObject] rect]); |
242 LocationBarViewMac::PageActionImageView* view = | |
243 page_action_views_->ViewAt(i); | |
244 NSImage* image = view->GetImage(); | |
245 if (image && view->IsVisible()) { | |
246 width += [image size].width + kIconHorizontalPad; | |
247 } | |
248 } | |
249 | |
250 if (security_image_view_ && security_image_view_->IsVisible()) { | |
251 width += [security_image_view_->GetImage() size].width + | |
252 kIconHorizontalPad; | |
253 NSAttributedString* label = security_image_view_->GetLabel(); | |
254 if (label) { | |
255 width += ceil([label size].width) + kHintXOffset; | |
256 } | |
257 } | |
258 if (width > 0) | 256 if (width > 0) |
259 width += kIconHorizontalPad; | 257 width += kIconHorizontalPad; |
260 | 258 if (width < NSWidth(cellFrame)) |
261 if (width < NSWidth(cellFrame)) { | |
262 textFrame.size.width -= width; | 259 textFrame.size.width -= width; |
263 } | |
264 } | 260 } |
265 | 261 |
266 return textFrame; | 262 return textFrame; |
267 } | 263 } |
268 | 264 |
269 // Returns a rect of size |imageSize| centered vertically and right-justified in | 265 // Returns a rect of size |imageSize| centered vertically and right-justified in |
270 // the |box|, with its top left corner |margin| pixels from the right end of the | 266 // the |box|, with its top left corner |margin| pixels from the right end of the |
271 // box. (The image thus occupies part of the |margin|.) | 267 // box. (The image thus occupies part of the |margin|.) |
272 - (NSRect)rightJustifyImage:(NSSize)imageSize | 268 - (NSRect)rightJustifyImage:(NSSize)imageSize |
273 inRect:(NSRect)box | 269 inRect:(NSRect)box |
(...skipping 27 matching lines...) Expand all Loading... |
301 // containing LocationViewMac object has already been destructed | 297 // containing LocationViewMac object has already been destructed |
302 // (happens sometimes during window shutdown). | 298 // (happens sometimes during window shutdown). |
303 if (!page_action_views_) | 299 if (!page_action_views_) |
304 return 0; | 300 return 0; |
305 return page_action_views_->Count(); | 301 return page_action_views_->Count(); |
306 } | 302 } |
307 | 303 |
308 - (NSRect)pageActionFrameForIndex:(size_t)index inFrame:(NSRect)cellFrame { | 304 - (NSRect)pageActionFrameForIndex:(size_t)index inFrame:(NSRect)cellFrame { |
309 LocationBarViewMac::PageActionImageView* view = | 305 LocationBarViewMac::PageActionImageView* view = |
310 page_action_views_->ViewAt(index); | 306 page_action_views_->ViewAt(index); |
311 const NSImage* icon = view->GetImage(); | |
312 | 307 |
313 // If we are calculating space for a preview page action, the icon is still | 308 // If we are calculating space for a preview page action, the icon is still |
314 // loading. We use this function only to get the correct x value for the | 309 // loading. We use this function only to get the correct x value for the |
315 // extension installed bubble arrow. | 310 // extension installed bubble arrow. |
316 if (!view->preview_enabled() && | 311 if (!view->preview_enabled() && |
317 (!icon || !view->IsVisible())) { | 312 (!view->GetImage() || !view->IsVisible())) { |
318 return NSZeroRect; | 313 return NSZeroRect; |
319 } | 314 } |
320 | 315 |
321 // Compute the amount of space used by this icon plus any other icons to its | 316 for (AutocompleteTextFieldIcon* icon in [self layedOutIcons:cellFrame]) { |
322 // right. It's terribly inefficient to do this anew every time, but easy to | 317 if (view == [icon view]) |
323 // understand. It should be fine for 5 or 10 installed Page Actions, perhaps | 318 return [icon rect]; |
324 // too slow for 100. | |
325 // TODO(pamg): Refactor to avoid this if performance is a problem. | |
326 const NSRect securityIconRect = [self securityImageFrameForFrame:cellFrame]; | |
327 CGFloat widthUsed = 0.0; | |
328 if (NSWidth(securityIconRect) > 0) { | |
329 widthUsed += NSMaxX(cellFrame) - NSMinX(securityIconRect); | |
330 } | 319 } |
331 for (size_t i = 0; i <= index; ++i) { | 320 NOTREACHED(); |
332 view = page_action_views_->ViewAt(i); | 321 return NSZeroRect; |
333 if (view->IsVisible()) { | |
334 NSImage* image = view->GetImage(); | |
335 if (image) { | |
336 // Page Action icons don't have labels. Don't compute space for them. | |
337 widthUsed += [image size].width + kIconHorizontalPad; | |
338 } | |
339 } | |
340 } | |
341 widthUsed += kIconHorizontalPad; | |
342 | |
343 // If we are calculating frame space for a preview, the icon is still | |
344 // loading -- use maximum size as a placeholder. | |
345 NSSize iconSize = view->GetImageSize(); | |
346 | |
347 return [self rightJustifyImage:iconSize | |
348 inRect:cellFrame | |
349 withMargin:widthUsed]; | |
350 } | |
351 | |
352 - (NSString*)pageActionToolTipForIndex:(size_t)index { | |
353 return page_action_views_->ViewAt(index)->GetToolTip(); | |
354 } | |
355 | |
356 - (ExtensionAction*)pageActionForIndex:(size_t)index { | |
357 return page_action_views_->ViewAt(index)->page_action(); | |
358 } | 322 } |
359 | 323 |
360 - (void)drawHintWithFrame:(NSRect)cellFrame inView:(NSView*)controlView { | 324 - (void)drawHintWithFrame:(NSRect)cellFrame inView:(NSView*)controlView { |
361 DCHECK(hintString_); | 325 DCHECK(hintString_); |
362 | 326 |
363 NSRect textFrame = [self textFrameForFrame:cellFrame]; | 327 NSRect textFrame = [self textFrameForFrame:cellFrame]; |
364 NSRect infoFrame(NSMakeRect(NSMaxX(textFrame), | 328 NSRect infoFrame(NSMakeRect(NSMaxX(textFrame), |
365 cellFrame.origin.y + kHintYOffset, | 329 cellFrame.origin.y + kHintYOffset, |
366 ceil([hintString_ size].width), | 330 ceil([hintString_ size].width), |
367 cellFrame.size.height - kHintYOffset)); | 331 cellFrame.size.height - kHintYOffset)); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
423 operation:NSCompositeSourceOver | 387 operation:NSCompositeSourceOver |
424 fraction:1.0]; | 388 fraction:1.0]; |
425 } | 389 } |
426 | 390 |
427 - (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView*)controlView { | 391 - (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView*)controlView { |
428 if (hintString_) { | 392 if (hintString_) { |
429 [self drawHintWithFrame:cellFrame inView:controlView]; | 393 [self drawHintWithFrame:cellFrame inView:controlView]; |
430 } else if (keywordString_) { | 394 } else if (keywordString_) { |
431 [self drawKeywordWithFrame:cellFrame inView:controlView]; | 395 [self drawKeywordWithFrame:cellFrame inView:controlView]; |
432 } else { | 396 } else { |
433 if (security_image_view_ && security_image_view_->IsVisible()) { | 397 for (AutocompleteTextFieldIcon* icon in [self layedOutIcons:cellFrame]) { |
434 [self drawImageView:security_image_view_ | 398 [self drawImageView:[icon view] |
435 inFrame:[self securityImageFrameForFrame:cellFrame] | 399 inFrame:[icon rect] |
436 inView:controlView]; | 400 inView:controlView]; |
437 } | 401 } |
438 | |
439 const size_t pageActionCount = [self pageActionCount]; | |
440 for (size_t i = 0; i < pageActionCount; ++i) { | |
441 LocationBarViewMac::PageActionImageView* view = | |
442 page_action_views_->ViewAt(i); | |
443 if (view && view->IsVisible()) { | |
444 [self drawImageView:view | |
445 inFrame:[self pageActionFrameForIndex:i inFrame:cellFrame] | |
446 inView:controlView]; | |
447 } | |
448 } | |
449 } | 402 } |
450 | 403 |
451 [super drawInteriorWithFrame:cellFrame inView:controlView]; | 404 [super drawInteriorWithFrame:cellFrame inView:controlView]; |
452 } | 405 } |
453 | 406 |
| 407 - (NSArray*)layedOutIcons:(NSRect)cellFrame { |
| 408 NSMutableArray* result = [NSMutableArray arrayWithCapacity:0]; |
| 409 NSRect iconFrame = cellFrame; |
| 410 if (security_image_view_ && security_image_view_->IsVisible()) { |
| 411 NSRect securityImageFrame = [self securityImageFrameForFrame:iconFrame]; |
| 412 [result addObject: |
| 413 [AutocompleteTextFieldIcon iconWithRect:securityImageFrame |
| 414 view:security_image_view_]]; |
| 415 iconFrame.size.width -= NSMaxX(iconFrame) - NSMinX(securityImageFrame); |
| 416 } |
| 417 |
| 418 const size_t pageActionCount = [self pageActionCount]; |
| 419 for (size_t i = 0; i < pageActionCount; ++i) { |
| 420 LocationBarViewMac::PageActionImageView* view = |
| 421 page_action_views_->ViewAt(i); |
| 422 if (view->preview_enabled() || (view->GetImage() && view->IsVisible())) { |
| 423 NSSize iconSize = view->GetImageSize(); |
| 424 NSRect pageActionFrame = |
| 425 [self rightJustifyImage:iconSize |
| 426 inRect:iconFrame |
| 427 withMargin:kIconHorizontalPad + iconSize.width]; |
| 428 [result addObject: |
| 429 [AutocompleteTextFieldIcon iconWithRect:pageActionFrame view:view]]; |
| 430 iconFrame.size.width -= NSMaxX(iconFrame) - NSMinX(pageActionFrame); |
| 431 } |
| 432 } |
| 433 |
| 434 if (content_blocked_views_) { |
| 435 // We use a reverse_iterator here because we're laying out the views from |
| 436 // right to left but in the vector they're ordered left to right. |
| 437 for (LocationBarViewMac::ContentBlockedViews::const_reverse_iterator |
| 438 it(content_blocked_views_->rbegin()); |
| 439 it != const_cast<const LocationBarViewMac::ContentBlockedViews*>( |
| 440 content_blocked_views_)->rend(); |
| 441 ++it) { |
| 442 if ((*it)->IsVisible()) { |
| 443 NSImage* image = (*it)->GetImage(); |
| 444 NSRect blockedContentFrame = |
| 445 [self rightJustifyImage:[image size] |
| 446 inRect:iconFrame |
| 447 withMargin:[image size].width + kIconHorizontalPad]; |
| 448 [result addObject: |
| 449 [AutocompleteTextFieldIcon iconWithRect:blockedContentFrame |
| 450 view:*it]]; |
| 451 iconFrame.size.width -= NSMaxX(iconFrame) - NSMinX(blockedContentFrame); |
| 452 } |
| 453 } |
| 454 } |
| 455 return result; |
| 456 } |
| 457 |
454 @end | 458 @end |
OLD | NEW |