| 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 |