| 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 #import "base/logging.h" | 9 #import "base/logging.h" |
| 10 #import "third_party/GTM/AppKit/GTMTheme.h" | 10 #import "third_party/GTM/AppKit/GTMTheme.h" |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 57 } | 57 } |
| 58 CGFloat WidthForKeyword(NSAttributedString* keywordString) { | 58 CGFloat WidthForKeyword(NSAttributedString* keywordString) { |
| 59 return kKeywordXOffset + ceil([keywordString size].width) + | 59 return kKeywordXOffset + ceil([keywordString size].width) + |
| 60 2 * kKeywordTokenInset; | 60 2 * kKeywordTokenInset; |
| 61 } | 61 } |
| 62 | 62 |
| 63 } // namespace | 63 } // namespace |
| 64 | 64 |
| 65 @implementation AutocompleteTextFieldCell | 65 @implementation AutocompleteTextFieldCell |
| 66 | 66 |
| 67 @synthesize fieldEditorNeedsReset = fieldEditorNeedsReset_; | |
| 68 | |
| 69 // @synthesize doesn't seem to compile for this transition. | 67 // @synthesize doesn't seem to compile for this transition. |
| 70 - (NSAttributedString*)keywordString { | 68 - (NSAttributedString*)keywordString { |
| 71 return keywordString_.get(); | 69 return keywordString_.get(); |
| 72 } | 70 } |
| 73 - (NSAttributedString*)hintString { | 71 - (NSAttributedString*)hintString { |
| 74 return hintString_.get(); | 72 return hintString_.get(); |
| 75 } | 73 } |
| 76 | 74 |
| 77 - (void)setKeywordString:(NSString*)fullString | 75 - (void)setKeywordString:(NSString*)fullString |
| 78 partialString:(NSString*)partialString | 76 partialString:(NSString*)partialString |
| 79 availableWidth:(CGFloat)width { | 77 availableWidth:(CGFloat)width { |
| 80 DCHECK(fullString != nil); | 78 DCHECK(fullString != nil); |
| 81 | 79 |
| 82 // Overriding |hintString_| always requires a reset. | 80 hintString_.reset(); |
| 83 if (hintString_) { | |
| 84 hintString_.reset(); | |
| 85 fieldEditorNeedsReset_ = YES; | |
| 86 } | |
| 87 | 81 |
| 88 // Adjust for space between editor and decorations. | 82 // Adjust for space between editor and decorations. |
| 89 width -= 2 * kEditorHorizontalInset; | 83 width -= 2 * kEditorHorizontalInset; |
| 90 | 84 |
| 91 // If |fullString| won't fit, choose |partialString|. | 85 // If |fullString| won't fit, choose |partialString|. |
| 92 NSDictionary* attributes = | 86 NSDictionary* attributes = |
| 93 [NSDictionary dictionaryWithObject:[self font] | 87 [NSDictionary dictionaryWithObject:[self font] |
| 94 forKey:NSFontAttributeName]; | 88 forKey:NSFontAttributeName]; |
| 95 NSString* s = fullString; | 89 NSString* s = fullString; |
| 96 if ([s sizeWithAttributes:attributes].width > width) { | 90 if ([s sizeWithAttributes:attributes].width > width) { |
| 97 if (partialString) { | 91 if (partialString) { |
| 98 s = partialString; | 92 s = partialString; |
| 99 } | 93 } |
| 100 } | 94 } |
| 101 scoped_nsobject<NSAttributedString> as( | 95 keywordString_.reset( |
| 102 [[NSAttributedString alloc] initWithString:s attributes:attributes]); | 96 [[NSAttributedString alloc] initWithString:s attributes:attributes]); |
| 103 | 97 |
| 104 // If the value has changed, require a reset. | |
| 105 if (![keywordString_ isEqualToAttributedString:as]) { | |
| 106 keywordString_.reset([as retain]); | |
| 107 fieldEditorNeedsReset_ = YES; | |
| 108 } | |
| 109 } | 98 } |
| 110 | 99 |
| 111 // Convenience for the attributes used in the right-justified info | 100 // Convenience for the attributes used in the right-justified info |
| 112 // cells. | 101 // cells. |
| 113 - (NSDictionary*)hintAttributes { | 102 - (NSDictionary*)hintAttributes { |
| 114 scoped_nsobject<NSMutableParagraphStyle> style( | 103 scoped_nsobject<NSMutableParagraphStyle> style( |
| 115 [[NSMutableParagraphStyle alloc] init]); | 104 [[NSMutableParagraphStyle alloc] init]); |
| 116 [style setAlignment:NSRightTextAlignment]; | 105 [style setAlignment:NSRightTextAlignment]; |
| 117 | 106 |
| 118 return [NSDictionary dictionaryWithObjectsAndKeys: | 107 return [NSDictionary dictionaryWithObjectsAndKeys: |
| 119 [self font], NSFontAttributeName, | 108 [self font], NSFontAttributeName, |
| 120 [NSColor lightGrayColor], NSForegroundColorAttributeName, | 109 [NSColor lightGrayColor], NSForegroundColorAttributeName, |
| 121 style.get(), NSParagraphStyleAttributeName, | 110 style.get(), NSParagraphStyleAttributeName, |
| 122 nil]; | 111 nil]; |
| 123 } | 112 } |
| 124 | 113 |
| 125 - (void)setKeywordHintPrefix:(NSString*)prefixString | 114 - (void)setKeywordHintPrefix:(NSString*)prefixString |
| 126 image:(NSImage*)anImage | 115 image:(NSImage*)anImage |
| 127 suffix:(NSString*)suffixString | 116 suffix:(NSString*)suffixString |
| 128 availableWidth:(CGFloat)width { | 117 availableWidth:(CGFloat)width { |
| 129 DCHECK(prefixString != nil); | 118 DCHECK(prefixString != nil); |
| 130 DCHECK(anImage != nil); | 119 DCHECK(anImage != nil); |
| 131 DCHECK(suffixString != nil); | 120 DCHECK(suffixString != nil); |
| 132 | 121 |
| 122 keywordString_.reset(); |
| 123 |
| 133 // Adjust for space between editor and decorations. | 124 // Adjust for space between editor and decorations. |
| 134 width -= 2 * kEditorHorizontalInset; | 125 width -= 2 * kEditorHorizontalInset; |
| 135 | 126 |
| 136 // Overriding |keywordString_| always requires a reset. | |
| 137 if (keywordString_) { | |
| 138 keywordString_.reset(); | |
| 139 fieldEditorNeedsReset_ = YES; | |
| 140 } | |
| 141 | |
| 142 // If |hintString_| is now too wide, clear it so that we don't pass | 127 // If |hintString_| is now too wide, clear it so that we don't pass |
| 143 // the equality tests. | 128 // the equality tests. |
| 144 if (hintString_ && WidthForHint(hintString_) > width) { | 129 if (hintString_ && WidthForHint(hintString_) > width) { |
| 145 [self clearKeywordAndHint]; | 130 [self clearKeywordAndHint]; |
| 146 } | 131 } |
| 147 | 132 |
| 148 // TODO(shess): Also check the length? | 133 // TODO(shess): Also check the length? |
| 149 if (![[hintString_ string] hasPrefix:prefixString] || | 134 if (![[hintString_ string] hasPrefix:prefixString] || |
| 150 ![[hintString_ string] hasSuffix:suffixString]) { | 135 ![[hintString_ string] hasSuffix:suffixString]) { |
| 151 | 136 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 171 mutableCopy]); | 156 mutableCopy]); |
| 172 [is addAttribute:NSBaselineOffsetAttributeName | 157 [is addAttribute:NSBaselineOffsetAttributeName |
| 173 value:[NSNumber numberWithFloat:kKeywordHintImageBaseline] | 158 value:[NSNumber numberWithFloat:kKeywordHintImageBaseline] |
| 174 range:NSMakeRange(0, [is length])]; | 159 range:NSMakeRange(0, [is length])]; |
| 175 | 160 |
| 176 // Stuff the image attachment between the prefix and suffix. | 161 // Stuff the image attachment between the prefix and suffix. |
| 177 [as insertAttributedString:is atIndex:[prefixString length]]; | 162 [as insertAttributedString:is atIndex:[prefixString length]]; |
| 178 | 163 |
| 179 // If too wide, just show the image. | 164 // If too wide, just show the image. |
| 180 hintString_.reset(WidthForHint(as) > width ? [is copy] : [as copy]); | 165 hintString_.reset(WidthForHint(as) > width ? [is copy] : [as copy]); |
| 181 | |
| 182 fieldEditorNeedsReset_ = YES; | |
| 183 } | 166 } |
| 184 } | 167 } |
| 185 | 168 |
| 186 - (void)setSearchHintString:(NSString*)aString | 169 - (void)setSearchHintString:(NSString*)aString |
| 187 availableWidth:(CGFloat)width { | 170 availableWidth:(CGFloat)width { |
| 188 DCHECK(aString != nil); | 171 DCHECK(aString != nil); |
| 189 | 172 |
| 190 // Adjust for space between editor and decorations. | 173 // Adjust for space between editor and decorations. |
| 191 width -= 2 * kEditorHorizontalInset; | 174 width -= 2 * kEditorHorizontalInset; |
| 192 | 175 |
| 193 // Overriding |keywordString_| always requires a reset. | 176 keywordString_.reset(); |
| 194 if (keywordString_) { | |
| 195 keywordString_.reset(); | |
| 196 fieldEditorNeedsReset_ = YES; | |
| 197 } | |
| 198 | 177 |
| 199 // If |hintString_| is now too wide, clear it so that we don't pass | 178 // If |hintString_| is now too wide, clear it so that we don't pass |
| 200 // the equality tests. | 179 // the equality tests. |
| 201 if (hintString_ && WidthForHint(hintString_) > width) { | 180 if (hintString_ && WidthForHint(hintString_) > width) { |
| 202 [self clearKeywordAndHint]; | 181 [self clearKeywordAndHint]; |
| 203 } | 182 } |
| 204 | 183 |
| 205 if (![[hintString_ string] isEqualToString:aString]) { | 184 if (![[hintString_ string] isEqualToString:aString]) { |
| 206 scoped_nsobject<NSAttributedString> as( | 185 scoped_nsobject<NSAttributedString> as( |
| 207 [[NSAttributedString alloc] initWithString:aString | 186 [[NSAttributedString alloc] initWithString:aString |
| 208 attributes:[self hintAttributes]]); | 187 attributes:[self hintAttributes]]); |
| 209 | 188 |
| 210 // If too wide, don't keep the hint. | 189 // If too wide, don't keep the hint. |
| 211 hintString_.reset(WidthForHint(as) > width ? nil : [as copy]); | 190 hintString_.reset(WidthForHint(as) > width ? nil : [as copy]); |
| 212 | |
| 213 fieldEditorNeedsReset_ = YES; | |
| 214 } | 191 } |
| 215 } | 192 } |
| 216 | 193 |
| 217 - (void)clearKeywordAndHint { | 194 - (void)clearKeywordAndHint { |
| 218 if (keywordString_ || hintString_) { | 195 keywordString_.reset(); |
| 219 keywordString_.reset(); | 196 hintString_.reset(); |
| 220 hintString_.reset(); | |
| 221 | |
| 222 fieldEditorNeedsReset_ = YES; | |
| 223 } | |
| 224 } | 197 } |
| 225 | 198 |
| 226 - (void)setHintIcon:(NSImage*)icon | 199 - (void)setHintIcon:(NSImage*)icon |
| 227 label:(NSString*)label | 200 label:(NSString*)label |
| 228 color:(NSColor*)color { | 201 color:(NSColor*)color { |
| 229 // Create an attributed string for the label, if a label was given. | 202 // Create an attributed string for the label, if a label was given. |
| 230 NSAttributedString* as = nil; | 203 NSAttributedString* as = nil; |
| 231 if (label) { | 204 if (label) { |
| 232 DCHECK(color); | 205 DCHECK(color); |
| 233 NSFont *baseFont = [self font]; | 206 NSFont *baseFont = [self font]; |
| 234 NSFont *font = [NSFont fontWithDescriptor:[baseFont fontDescriptor] | 207 NSFont *font = [NSFont fontWithDescriptor:[baseFont fontDescriptor] |
| 235 size:[baseFont pointSize] - 2.0]; | 208 size:[baseFont pointSize] - 2.0]; |
| 236 NSDictionary* attributes = | 209 NSDictionary* attributes = |
| 237 [NSDictionary dictionaryWithObjectsAndKeys: | 210 [NSDictionary dictionaryWithObjectsAndKeys: |
| 238 color, NSForegroundColorAttributeName, | 211 color, NSForegroundColorAttributeName, |
| 239 font, NSFontAttributeName, | 212 font, NSFontAttributeName, |
| 240 NULL]; | 213 NULL]; |
| 241 as = [[[NSAttributedString alloc] initWithString:label | 214 as = [[[NSAttributedString alloc] initWithString:label |
| 242 attributes:attributes] autorelease]; | 215 attributes:attributes] autorelease]; |
| 243 } | 216 } |
| 244 | 217 |
| 245 // Did the icon change? Is there a label now but there wasn't before, | 218 hintIconLabel_.reset([as retain]); |
| 246 // or vice-versa? Did the label change? | 219 hintIcon_.reset([icon retain]); |
| 247 if (icon != hintIcon_.get() || (as && !hintIconLabel_.get()) || | |
| 248 (!as && hintIconLabel_.get()) || | |
| 249 (as && ![hintIconLabel_.get() isEqualToAttributedString:as])) { | |
| 250 hintIconLabel_.reset([as retain]); | |
| 251 hintIcon_.reset([icon retain]); | |
| 252 if (!keywordString_ && !hintString_) { | |
| 253 // Redraw if the icon is visible. | |
| 254 fieldEditorNeedsReset_ = YES; | |
| 255 } | |
| 256 } | |
| 257 } | 220 } |
| 258 | 221 |
| 259 // TODO(shess): This code is manually drawing the cell's border area, | 222 // TODO(shess): This code is manually drawing the cell's border area, |
| 260 // but otherwise the cell assumes -setBordered:YES for purposes of | 223 // but otherwise the cell assumes -setBordered:YES for purposes of |
| 261 // calculating things like the editing area. This is probably | 224 // calculating things like the editing area. This is probably |
| 262 // incorrect. I know that this affects -drawingRectForBounds:. | 225 // incorrect. I know that this affects -drawingRectForBounds:. |
| 263 | 226 |
| 264 - (void)drawWithFrame:(NSRect)cellFrame inView:(NSView*)controlView { | 227 - (void)drawWithFrame:(NSRect)cellFrame inView:(NSView*)controlView { |
| 265 DCHECK([controlView isFlipped]); | 228 DCHECK([controlView isFlipped]); |
| 266 [[NSColor colorWithCalibratedWhite:1.0 alpha:0.25] set]; | 229 [[NSColor colorWithCalibratedWhite:1.0 alpha:0.25] set]; |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 446 | 409 |
| 447 [super drawInteriorWithFrame:cellFrame inView:controlView]; | 410 [super drawInteriorWithFrame:cellFrame inView:controlView]; |
| 448 } | 411 } |
| 449 | 412 |
| 450 - (void)resetCursorRect:(NSRect)cellFrame inView:(NSView *)controlView { | 413 - (void)resetCursorRect:(NSRect)cellFrame inView:(NSView *)controlView { |
| 451 [super resetCursorRect:[self textCursorFrameForFrame:cellFrame] | 414 [super resetCursorRect:[self textCursorFrameForFrame:cellFrame] |
| 452 inView:controlView]; | 415 inView:controlView]; |
| 453 } | 416 } |
| 454 | 417 |
| 455 @end | 418 @end |
| OLD | NEW |