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 |