| 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" |
| 8 #include "app/resource_bundle.h" |
| 7 #import "base/logging.h" | 9 #import "base/logging.h" |
| 8 #import "third_party/GTM/AppKit/GTMTheme.h" | 10 #import "third_party/GTM/AppKit/GTMTheme.h" |
| 9 | 11 |
| 10 namespace { | 12 namespace { |
| 11 | 13 |
| 12 const NSInteger kBaselineAdjust = 2; | 14 const NSInteger kBaselineAdjust = 2; |
| 13 | 15 |
| 14 // How far to offset the keyword token into the field. | 16 // How far to offset the keyword token into the field. |
| 15 const NSInteger kKeywordXOffset = 3; | 17 const NSInteger kKeywordXOffset = 3; |
| 16 | 18 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 33 // above the lowercase ascender as below the baseline. A better | 35 // above the lowercase ascender as below the baseline. A better |
| 34 // technique would be nice to have, though. | 36 // technique would be nice to have, though. |
| 35 const NSInteger kKeywordHintImageBaseline = -6; | 37 const NSInteger kKeywordHintImageBaseline = -6; |
| 36 | 38 |
| 37 // Offset from the bottom of the field for drawing decoration text. | 39 // Offset from the bottom of the field for drawing decoration text. |
| 38 // TODO(shess): Somehow determine the baseline for the text field and | 40 // TODO(shess): Somehow determine the baseline for the text field and |
| 39 // use that. | 41 // use that. |
| 40 const NSInteger kBaselineOffset = 4; | 42 const NSInteger kBaselineOffset = 4; |
| 41 | 43 |
| 42 // The amount of padding on either side reserved for drawing the hint icon | 44 // The amount of padding on either side reserved for drawing the hint icon |
| 43 const NSInteger kHintIconHorizontalPad = 5; | 45 const NSInteger kHintIconHorizontalPad = 3; |
| 46 |
| 47 // How far to shift bounding box of hint icon label down from top of field. |
| 48 const NSInteger kHintIconLabelYOffset = 7; |
| 44 | 49 |
| 45 } // namespace | 50 } // namespace |
| 46 | 51 |
| 47 @implementation AutocompleteTextFieldCell | 52 @implementation AutocompleteTextFieldCell |
| 48 | 53 |
| 49 @synthesize fieldEditorNeedsReset = fieldEditorNeedsReset_; | 54 @synthesize fieldEditorNeedsReset = fieldEditorNeedsReset_; |
| 50 | 55 |
| 51 // @synthesize doesn't seem to compile for this transition. | 56 // @synthesize doesn't seem to compile for this transition. |
| 52 - (NSAttributedString*)keywordString { | 57 - (NSAttributedString*)keywordString { |
| 53 return keywordString_.get(); | 58 return keywordString_.get(); |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 152 | 157 |
| 153 - (void)clearKeywordAndHint { | 158 - (void)clearKeywordAndHint { |
| 154 if (keywordString_ || hintString_) { | 159 if (keywordString_ || hintString_) { |
| 155 keywordString_.reset(); | 160 keywordString_.reset(); |
| 156 hintString_.reset(); | 161 hintString_.reset(); |
| 157 | 162 |
| 158 fieldEditorNeedsReset_ = YES; | 163 fieldEditorNeedsReset_ = YES; |
| 159 } | 164 } |
| 160 } | 165 } |
| 161 | 166 |
| 162 - (void)setHintIcon:(NSImage*)icon { | 167 - (void)setHintIcon:(NSImage*)icon |
| 163 if (icon != hintIcon_) { | 168 label:(NSString*)label |
| 169 color:(NSColor*)color { |
| 170 // Create an attributed string for the label, if a label was given. |
| 171 NSAttributedString* as = nil; |
| 172 if (label) { |
| 173 DCHECK(color); |
| 174 NSFont *baseFont = [self font]; |
| 175 NSFont *font = [NSFont fontWithDescriptor:[baseFont fontDescriptor] |
| 176 size:[baseFont pointSize] - 2.0]; |
| 177 NSDictionary* attributes = |
| 178 [NSDictionary dictionaryWithObjectsAndKeys: |
| 179 color, NSForegroundColorAttributeName, |
| 180 font, NSFontAttributeName, |
| 181 NULL]; |
| 182 as = [[[NSAttributedString alloc] initWithString:label |
| 183 attributes:attributes] autorelease]; |
| 184 } |
| 185 |
| 186 // Did the icon change? Is there a label now but there wasn't before, |
| 187 // or vice-versa? Did the label change? |
| 188 if (icon != hintIcon_.get() || (as && !hintIconLabel_.get()) || |
| 189 (!as && hintIconLabel_.get()) || |
| 190 (as && ![hintIconLabel_.get() isEqualToAttributedString:as])) { |
| 191 hintIconLabel_.reset([as retain]); |
| 164 hintIcon_.reset([icon retain]); | 192 hintIcon_.reset([icon retain]); |
| 165 if (!keywordString_ && !hintString_) { | 193 if (!keywordString_ && !hintString_) { |
| 194 // Redraw if the icon is visible. |
| 166 fieldEditorNeedsReset_ = YES; | 195 fieldEditorNeedsReset_ = YES; |
| 167 } | 196 } |
| 168 } | 197 } |
| 169 } | 198 } |
| 170 | 199 |
| 171 // TODO(shess): This code is manually drawing the cell's border area, | 200 // TODO(shess): This code is manually drawing the cell's border area, |
| 172 // but otherwise the cell assumes -setBordered:YES for purposes of | 201 // but otherwise the cell assumes -setBordered:YES for purposes of |
| 173 // calculating things like the editing area. This is probably | 202 // calculating things like the editing area. This is probably |
| 174 // incorrect. I know that this affects -drawingRectForBounds:. | 203 // incorrect. I know that this affects -drawingRectForBounds:. |
| 175 | 204 |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 232 // TODO(shess): This could be better. There's support for a | 261 // TODO(shess): This could be better. There's support for a |
| 233 // "short" version of the keyword string, work that in in a | 262 // "short" version of the keyword string, work that in in a |
| 234 // follow-on pass. | 263 // follow-on pass. |
| 235 if (keywordWidth < NSWidth(cellFrame)) { | 264 if (keywordWidth < NSWidth(cellFrame)) { |
| 236 textFrame.origin.x += keywordWidth; | 265 textFrame.origin.x += keywordWidth; |
| 237 textFrame.size.width = NSMaxX(cellFrame) - NSMinX(textFrame); | 266 textFrame.size.width = NSMaxX(cellFrame) - NSMinX(textFrame); |
| 238 } | 267 } |
| 239 } else if (hintIcon_) { | 268 } else if (hintIcon_) { |
| 240 CGFloat width = [hintIcon_ size].width; | 269 CGFloat width = [hintIcon_ size].width; |
| 241 width += kHintIconHorizontalPad * 2; | 270 width += kHintIconHorizontalPad * 2; |
| 271 if (hintIconLabel_) { |
| 272 width += ceil([hintIconLabel_ size].width) + kHintXOffset; |
| 273 } |
| 242 if (width < NSWidth(cellFrame)) { | 274 if (width < NSWidth(cellFrame)) { |
| 243 textFrame.size.width -= width; | 275 textFrame.size.width -= width; |
| 244 } | 276 } |
| 245 } | 277 } |
| 246 | 278 |
| 247 return textFrame; | 279 return textFrame; |
| 248 } | 280 } |
| 249 | 281 |
| 250 // For NSTextFieldCell this is the area within the borders. For our | 282 // For NSTextFieldCell this is the area within the borders. For our |
| 251 // purposes, we count the info decorations as being part of the | 283 // purposes, we count the info decorations as being part of the |
| 252 // border. | 284 // border. |
| 253 - (NSRect)drawingRectForBounds:(NSRect)theRect { | 285 - (NSRect)drawingRectForBounds:(NSRect)theRect { |
| 254 return [super drawingRectForBounds:[self textFrameForFrame:theRect]]; | 286 return [super drawingRectForBounds:[self textFrameForFrame:theRect]]; |
| 255 } | 287 } |
| 256 | 288 |
| 257 - (NSRect)hintImageFrameForFrame:(NSRect)cellFrame { | 289 - (NSRect)hintImageFrameForFrame:(NSRect)cellFrame { |
| 258 // We'll draw the entire image | 290 // We'll draw the entire image |
| 259 const NSSize imageRect([hintIcon_ size]); | 291 const NSSize imageRect([hintIcon_ size]); |
| 260 | 292 |
| 261 // Move the rect that we're drawing into to the far right | 293 CGFloat labelWidth = 0; |
| 294 if (hintIconLabel_) { |
| 295 labelWidth = ceil([hintIconLabel_ size].width) + kHintXOffset; |
| 296 } |
| 297 |
| 298 // Move the rect that we're drawing into to the far right, minus |
| 299 // enough space for the label (if present) |
| 262 cellFrame.origin.x += cellFrame.size.width - imageRect.width; | 300 cellFrame.origin.x += cellFrame.size.width - imageRect.width; |
| 301 cellFrame.origin.x -= labelWidth; |
| 263 // Add back the padding | 302 // Add back the padding |
| 264 cellFrame.origin.x -= kHintIconHorizontalPad; | 303 cellFrame.origin.x -= kHintIconHorizontalPad; |
| 265 | 304 |
| 266 // Center the image vertically in the frame | 305 // Center the image vertically in the frame |
| 267 cellFrame.origin.y += | 306 cellFrame.origin.y += |
| 268 floor((cellFrame.size.height - imageRect.height) / 2); | 307 floor((cellFrame.size.height - imageRect.height) / 2); |
| 269 | 308 |
| 270 // Set the drawing size to the image size | 309 // Set the drawing size to the image size |
| 271 cellFrame.size = imageRect; | 310 cellFrame.size = imageRect; |
| 272 | 311 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 309 [path stroke]; | 348 [path stroke]; |
| 310 | 349 |
| 311 // Draw text w/in the rectangle. | 350 // Draw text w/in the rectangle. |
| 312 infoFrame.origin.x += 4.0; | 351 infoFrame.origin.x += 4.0; |
| 313 infoFrame.origin.y += 1.0; | 352 infoFrame.origin.y += 1.0; |
| 314 [keywordString_.get() drawInRect:infoFrame]; | 353 [keywordString_.get() drawInRect:infoFrame]; |
| 315 } | 354 } |
| 316 | 355 |
| 317 - (void)drawHintIconWithFrame:(NSRect)cellFrame | 356 - (void)drawHintIconWithFrame:(NSRect)cellFrame |
| 318 inView:(NSView*)controlView { | 357 inView:(NSView*)controlView { |
| 358 // If there's a label, draw it to the right of the icon. |
| 359 CGFloat labelWidth = 0; |
| 360 if (hintIconLabel_) { |
| 361 labelWidth = ceil([hintIconLabel_ size].width) + kHintXOffset; |
| 362 NSRect textFrame(NSMakeRect(NSMaxX(cellFrame) - labelWidth, |
| 363 cellFrame.origin.y + kHintIconLabelYOffset, |
| 364 labelWidth, |
| 365 cellFrame.size.height - kHintIconLabelYOffset)); |
| 366 [hintIconLabel_.get() drawInRect:textFrame]; |
| 367 } |
| 368 |
| 319 // We'll draw the entire image | 369 // We'll draw the entire image |
| 320 NSRect imageRect = NSZeroRect; | 370 NSRect imageRect = NSZeroRect; |
| 321 imageRect.size = [hintIcon_ size]; | 371 imageRect.size = [hintIcon_ size]; |
| 322 const NSRect hintFrame([self hintImageFrameForFrame:cellFrame]); | 372 const NSRect hintFrame([self hintImageFrameForFrame:cellFrame]); |
| 323 | |
| 324 [hintIcon_ setFlipped:[controlView isFlipped]]; | 373 [hintIcon_ setFlipped:[controlView isFlipped]]; |
| 325 [hintIcon_ drawInRect:hintFrame | 374 [hintIcon_ drawInRect:hintFrame |
| 326 fromRect:imageRect | 375 fromRect:imageRect |
| 327 operation:NSCompositeSourceOver | 376 operation:NSCompositeSourceOver |
| 328 fraction:1.0]; | 377 fraction:1.0]; |
| 329 } | 378 } |
| 330 | 379 |
| 331 - (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView*)controlView { | 380 - (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView*)controlView { |
| 332 if (hintString_) { | 381 if (hintString_) { |
| 333 [self drawHintWithFrame:cellFrame inView:controlView]; | 382 [self drawHintWithFrame:cellFrame inView:controlView]; |
| 334 } else if (keywordString_) { | 383 } else if (keywordString_) { |
| 335 [self drawKeywordWithFrame:cellFrame inView:controlView]; | 384 [self drawKeywordWithFrame:cellFrame inView:controlView]; |
| 336 } else if (hintIcon_) { | 385 } else if (hintIcon_) { |
| 337 [self drawHintIconWithFrame:cellFrame inView:controlView]; | 386 [self drawHintIconWithFrame:cellFrame inView:controlView]; |
| 338 } | 387 } |
| 339 | 388 |
| 340 [super drawInteriorWithFrame:cellFrame inView:controlView]; | 389 [super drawInteriorWithFrame:cellFrame inView:controlView]; |
| 341 } | 390 } |
| 342 | 391 |
| 343 - (void)resetCursorRect:(NSRect)cellFrame inView:(NSView *)controlView { | 392 - (void)resetCursorRect:(NSRect)cellFrame inView:(NSView *)controlView { |
| 344 [super resetCursorRect:[self textCursorFrameForFrame:cellFrame] | 393 [super resetCursorRect:[self textCursorFrameForFrame:cellFrame] |
| 345 inView:controlView]; | 394 inView:controlView]; |
| 346 } | 395 } |
| 347 | 396 |
| 348 @end | 397 @end |
| OLD | NEW |