| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 "third_party/GTM/AppKit/GTMTheme.h" | 10 #import "third_party/GTM/AppKit/GTMTheme.h" |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 187 // If too wide, don't keep the hint. | 187 // If too wide, don't keep the hint. |
| 188 hintString_.reset(WidthForHint(as) > width ? nil : [as copy]); | 188 hintString_.reset(WidthForHint(as) > width ? nil : [as copy]); |
| 189 } | 189 } |
| 190 } | 190 } |
| 191 | 191 |
| 192 - (void)clearKeywordAndHint { | 192 - (void)clearKeywordAndHint { |
| 193 keywordString_.reset(); | 193 keywordString_.reset(); |
| 194 hintString_.reset(); | 194 hintString_.reset(); |
| 195 } | 195 } |
| 196 | 196 |
| 197 - (void)setPageActionViewList:(LocationBarViewMac::PageActionViewList*)list { |
| 198 page_action_views_ = list; |
| 199 } |
| 200 |
| 197 - (void)setSecurityImageView:(LocationBarViewMac::SecurityImageView*)view { | 201 - (void)setSecurityImageView:(LocationBarViewMac::SecurityImageView*)view { |
| 198 security_image_view_ = view; | 202 security_image_view_ = view; |
| 199 } | 203 } |
| 200 | 204 |
| 201 - (void)onSecurityIconMousePressed { | 205 - (void)onSecurityIconMousePressed { |
| 202 security_image_view_->OnMousePressed(); | 206 security_image_view_->OnMousePressed(); |
| 203 } | 207 } |
| 204 | 208 |
| 209 - (void)onPageActionMousePressedIn:(NSRect)iconFrame forIndex:(size_t)index { |
| 210 page_action_views_->OnMousePressed(iconFrame, index); |
| 211 } |
| 212 |
| 205 // Overriden to account for the hint strings and hint icons. | 213 // Overriden to account for the hint strings and hint icons. |
| 206 - (NSRect)textFrameForFrame:(NSRect)cellFrame { | 214 - (NSRect)textFrameForFrame:(NSRect)cellFrame { |
| 207 NSRect textFrame([super textFrameForFrame:cellFrame]); | 215 NSRect textFrame([super textFrameForFrame:cellFrame]); |
| 208 | 216 |
| 209 if (hintString_) { | 217 if (hintString_) { |
| 210 DCHECK(!keywordString_); | 218 DCHECK(!keywordString_); |
| 211 const CGFloat hintWidth(WidthForHint(hintString_)); | 219 const CGFloat hintWidth(WidthForHint(hintString_)); |
| 212 | 220 |
| 213 // TODO(shess): This could be better. Show the hint until the | 221 // TODO(shess): This could be better. Show the hint until the |
| 214 // non-hint text bumps against it? | 222 // non-hint text bumps against it? |
| 215 if (hintWidth < NSWidth(cellFrame)) { | 223 if (hintWidth < NSWidth(cellFrame)) { |
| 216 textFrame.size.width -= hintWidth; | 224 textFrame.size.width -= hintWidth; |
| 217 } | 225 } |
| 218 } else if (keywordString_) { | 226 } else if (keywordString_) { |
| 219 DCHECK(!hintString_); | 227 DCHECK(!hintString_); |
| 220 const CGFloat keywordWidth(WidthForKeyword(keywordString_)); | 228 const CGFloat keywordWidth(WidthForKeyword(keywordString_)); |
| 221 | 229 |
| 222 // TODO(shess): This could be better. There's support for a | 230 // TODO(shess): This could be better. There's support for a |
| 223 // "short" version of the keyword string, work that in in a | 231 // "short" version of the keyword string, work that in in a |
| 224 // follow-on pass. | 232 // follow-on pass. |
| 225 if (keywordWidth < NSWidth(cellFrame)) { | 233 if (keywordWidth < NSWidth(cellFrame)) { |
| 226 textFrame.origin.x += keywordWidth; | 234 textFrame.origin.x += keywordWidth; |
| 227 textFrame.size.width = NSMaxX(cellFrame) - NSMinX(textFrame); | 235 textFrame.size.width = NSMaxX(cellFrame) - NSMinX(textFrame); |
| 228 } | 236 } |
| 229 } else if (security_image_view_ && security_image_view_->IsVisible()) { | 237 } else { |
| 230 NSImage* image = security_image_view_->GetImage(); | 238 // Account for the lock icon, if any, and any visible Page Action icons. |
| 231 CGFloat width = [image size].width; | 239 CGFloat width = 0; |
| 232 width += kIconHorizontalPad * 2; | 240 const size_t iconCount = [self pageActionCount]; |
| 233 NSAttributedString* label = security_image_view_->GetLabel(); | 241 for (size_t i = 0; i < iconCount; ++i) { |
| 234 if (label) { | 242 LocationBarViewMac::PageActionImageView* view = |
| 235 width += ceil([label size].width) + kHintXOffset; | 243 page_action_views_->ViewAt(i); |
| 244 NSImage* image = view->GetImage(); |
| 245 if (image && view->IsVisible()) { |
| 246 width += [image size].width + kIconHorizontalPad; |
| 247 } |
| 236 } | 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) |
| 259 width += kIconHorizontalPad; |
| 260 |
| 237 if (width < NSWidth(cellFrame)) { | 261 if (width < NSWidth(cellFrame)) { |
| 238 textFrame.size.width -= width; | 262 textFrame.size.width -= width; |
| 239 } | 263 } |
| 240 } | 264 } |
| 241 | 265 |
| 242 return textFrame; | 266 return textFrame; |
| 243 } | 267 } |
| 244 | 268 |
| 245 - (NSRect)imageFrameForFrame:(NSRect)cellFrame | 269 // Returns a rect of size |imageSize| centered vertically and right-justified in |
| 246 withImageView:(LocationBarViewMac::LocationBarImageView*)image_view { | 270 // the |box|, with its top left corner |margin| pixels from the right end of the |
| 247 if (!image_view->IsVisible()) { | 271 // box. (The image thus occupies part of the |margin|.) |
| 248 return NSZeroRect; | 272 - (NSRect)rightJustifyImage:(NSSize)imageSize |
| 249 } | 273 inRect:(NSRect)box |
| 250 const NSSize imageRect = [image_view->GetImage() size]; | 274 withMargin:(CGFloat)margin { |
| 251 CGFloat labelWidth = 0; | 275 box.origin.x += box.size.width - margin; |
| 252 NSAttributedString* label = image_view->GetLabel(); | 276 box.origin.y += floor((box.size.height - imageSize.height) / 2); |
| 253 if (label) { | 277 box.size = imageSize; |
| 254 labelWidth = ceil([label size].width) + kHintXOffset; | 278 return box; |
| 255 } | |
| 256 | |
| 257 // Move the rect that we're drawing into to the far right, minus | |
| 258 // enough space for the label (if present). | |
| 259 cellFrame.origin.x += cellFrame.size.width - imageRect.width; | |
| 260 cellFrame.origin.x -= labelWidth; | |
| 261 // Add back the padding | |
| 262 cellFrame.origin.x -= kIconHorizontalPad; | |
| 263 | |
| 264 // Center the image vertically in the frame | |
| 265 cellFrame.origin.y += | |
| 266 floor((cellFrame.size.height - imageRect.height) / 2); | |
| 267 | |
| 268 // Set the drawing size to the image size | |
| 269 cellFrame.size = imageRect; | |
| 270 | |
| 271 return cellFrame; | |
| 272 } | 279 } |
| 273 | 280 |
| 274 - (NSRect)securityImageFrameForFrame:(NSRect)cellFrame { | 281 - (NSRect)securityImageFrameForFrame:(NSRect)cellFrame { |
| 275 if (!security_image_view_) { | 282 if (!security_image_view_ || !security_image_view_->IsVisible()) { |
| 276 return NSZeroRect; | 283 return NSZeroRect; |
| 277 } | 284 } |
| 278 return [self imageFrameForFrame:cellFrame withImageView:security_image_view_]; | 285 |
| 286 // Calculate the total width occupied by the image, label, and padding. |
| 287 NSSize imageSize = [security_image_view_->GetImage() size]; |
| 288 CGFloat widthUsed = imageSize.width + kIconHorizontalPad; |
| 289 NSAttributedString* label = security_image_view_->GetLabel(); |
| 290 if (label) { |
| 291 widthUsed += ceil([label size].width) + kHintXOffset; |
| 292 } |
| 293 |
| 294 return [self rightJustifyImage:imageSize |
| 295 inRect:cellFrame |
| 296 withMargin:widthUsed]; |
| 297 } |
| 298 |
| 299 - (size_t)pageActionCount { |
| 300 // page_action_views_ may be NULL during testing. |
| 301 if (!page_action_views_) |
| 302 return 0; |
| 303 return page_action_views_->Count(); |
| 304 } |
| 305 |
| 306 - (NSRect)pageActionFrameForIndex:(size_t)index inFrame:(NSRect)cellFrame { |
| 307 LocationBarViewMac::PageActionImageView* view = |
| 308 page_action_views_->ViewAt(index); |
| 309 const NSImage* icon = view->GetImage(); |
| 310 if (!icon || !view->IsVisible()) { |
| 311 return NSZeroRect; |
| 312 } |
| 313 |
| 314 // Compute the amount of space used by this icon plus any other icons to its |
| 315 // right. It's terribly inefficient to do this anew every time, but easy to |
| 316 // understand. It should be fine for 5 or 10 installed Page Actions, perhaps |
| 317 // too slow for 100. |
| 318 // TODO(pamg): Refactor to avoid this if performance is a problem. |
| 319 const NSRect securityIconRect = [self securityImageFrameForFrame:cellFrame]; |
| 320 CGFloat widthUsed = 0.0; |
| 321 if (NSWidth(securityIconRect) > 0) { |
| 322 widthUsed += NSMaxX(cellFrame) - NSMinX(securityIconRect); |
| 323 } |
| 324 for (size_t i = 0; i <= index; ++i) { |
| 325 view = page_action_views_->ViewAt(i); |
| 326 if (view->IsVisible()) { |
| 327 NSImage* image = view->GetImage(); |
| 328 if (image) { |
| 329 // Page Action icons don't have labels. Don't compute space for them. |
| 330 widthUsed += [image size].width + kIconHorizontalPad; |
| 331 } |
| 332 } |
| 333 } |
| 334 widthUsed += kIconHorizontalPad; |
| 335 |
| 336 return [self rightJustifyImage:[icon size] |
| 337 inRect:cellFrame |
| 338 withMargin:widthUsed]; |
| 279 } | 339 } |
| 280 | 340 |
| 281 - (void)drawHintWithFrame:(NSRect)cellFrame inView:(NSView*)controlView { | 341 - (void)drawHintWithFrame:(NSRect)cellFrame inView:(NSView*)controlView { |
| 282 DCHECK(hintString_); | 342 DCHECK(hintString_); |
| 283 | 343 |
| 284 NSRect textFrame = [self textFrameForFrame:cellFrame]; | 344 NSRect textFrame = [self textFrameForFrame:cellFrame]; |
| 285 NSRect infoFrame(NSMakeRect(NSMaxX(textFrame), | 345 NSRect infoFrame(NSMakeRect(NSMaxX(textFrame), |
| 286 cellFrame.origin.y + kHintYOffset, | 346 cellFrame.origin.y + kHintYOffset, |
| 287 ceil([hintString_ size].width), | 347 ceil([hintString_ size].width), |
| 288 cellFrame.size.height - kHintYOffset)); | 348 cellFrame.size.height - kHintYOffset)); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 312 [[[NSColor keyboardFocusIndicatorColor] colorWithAlphaComponent:0.5] set]; | 372 [[[NSColor keyboardFocusIndicatorColor] colorWithAlphaComponent:0.5] set]; |
| 313 [path setLineWidth:1.0]; | 373 [path setLineWidth:1.0]; |
| 314 [path stroke]; | 374 [path stroke]; |
| 315 | 375 |
| 316 // Draw text w/in the rectangle. | 376 // Draw text w/in the rectangle. |
| 317 infoFrame.origin.x += 4.0; | 377 infoFrame.origin.x += 4.0; |
| 318 infoFrame.origin.y += 1.0; | 378 infoFrame.origin.y += 1.0; |
| 319 [keywordString_.get() drawInRect:infoFrame]; | 379 [keywordString_.get() drawInRect:infoFrame]; |
| 320 } | 380 } |
| 321 | 381 |
| 322 - (void)drawImageView:(LocationBarViewMac::LocationBarImageView*)image_view | 382 - (void)drawImageView:(LocationBarViewMac::LocationBarImageView*)imageView |
| 323 withFrame:(NSRect)cellFrame | 383 inFrame:(NSRect)imageFrame |
| 324 inView:(NSView*)controlView { | 384 inView:(NSView*)controlView { |
| 325 // If there's a label, draw it to the right of the icon. | 385 // If there's a label, draw it to the right of the icon. The caller must have |
| 326 CGFloat labelWidth = 0; | 386 // left sufficient space. |
| 327 NSAttributedString* label = image_view->GetLabel(); | 387 NSAttributedString* label = imageView->GetLabel(); |
| 328 if (label) { | 388 if (label) { |
| 329 labelWidth = ceil([label size].width) + kHintXOffset; | 389 CGFloat labelWidth = ceil([label size].width) + kHintXOffset; |
| 330 NSRect textFrame(NSMakeRect(NSMaxX(cellFrame) - labelWidth, | 390 NSRect textFrame(NSMakeRect(NSMaxX(imageFrame) + kIconHorizontalPad, |
| 331 cellFrame.origin.y + kIconLabelYOffset, | 391 imageFrame.origin.y + kIconLabelYOffset, |
| 332 labelWidth, | 392 labelWidth, |
| 333 cellFrame.size.height - kIconLabelYOffset)); | 393 imageFrame.size.height - kIconLabelYOffset)); |
| 334 [label drawInRect:textFrame]; | 394 [label drawInRect:textFrame]; |
| 335 } | 395 } |
| 336 | 396 |
| 337 // Draw the entire image. | 397 // Draw the entire image. |
| 338 NSRect imageRect = NSZeroRect; | 398 NSRect imageRect = NSZeroRect; |
| 339 NSImage* image = image_view->GetImage(); | 399 NSImage* image = imageView->GetImage(); |
| 340 image.size = [image size]; | 400 image.size = [image size]; |
| 341 NSRect imageFrame([self imageFrameForFrame:cellFrame | |
| 342 withImageView:image_view]); | |
| 343 [image setFlipped:[controlView isFlipped]]; | 401 [image setFlipped:[controlView isFlipped]]; |
| 344 [image drawInRect:imageFrame | 402 [image drawInRect:imageFrame |
| 345 fromRect:imageRect | 403 fromRect:imageRect |
| 346 operation:NSCompositeSourceOver | 404 operation:NSCompositeSourceOver |
| 347 fraction:1.0]; | 405 fraction:1.0]; |
| 348 } | 406 } |
| 349 | 407 |
| 350 - (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView*)controlView { | 408 - (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView*)controlView { |
| 351 if (hintString_) { | 409 if (hintString_) { |
| 352 [self drawHintWithFrame:cellFrame inView:controlView]; | 410 [self drawHintWithFrame:cellFrame inView:controlView]; |
| 353 } else if (keywordString_) { | 411 } else if (keywordString_) { |
| 354 [self drawKeywordWithFrame:cellFrame inView:controlView]; | 412 [self drawKeywordWithFrame:cellFrame inView:controlView]; |
| 355 } else if (security_image_view_ && security_image_view_->IsVisible()) { | 413 } else { |
| 356 [self drawImageView:security_image_view_ | 414 if (security_image_view_ && security_image_view_->IsVisible()) { |
| 357 withFrame:cellFrame | 415 [self drawImageView:security_image_view_ |
| 358 inView:controlView]; | 416 inFrame:[self securityImageFrameForFrame:cellFrame] |
| 417 inView:controlView]; |
| 418 } |
| 419 |
| 420 const size_t pageActionCount = [self pageActionCount]; |
| 421 for (size_t i = 0; i < pageActionCount; ++i) { |
| 422 LocationBarViewMac::PageActionImageView* view = |
| 423 page_action_views_->ViewAt(i); |
| 424 if (view && view->IsVisible()) { |
| 425 [self drawImageView:view |
| 426 inFrame:[self pageActionFrameForIndex:i inFrame:cellFrame] |
| 427 inView:controlView]; |
| 428 } |
| 429 } |
| 359 } | 430 } |
| 360 | 431 |
| 361 [super drawInteriorWithFrame:cellFrame inView:controlView]; | 432 [super drawInteriorWithFrame:cellFrame inView:controlView]; |
| 362 } | 433 } |
| 363 | 434 |
| 364 @end | 435 @end |
| OLD | NEW |