Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(92)

Side by Side Diff: chrome/browser/cocoa/autocomplete_text_field_cell.mm

Issue 1581011: [Mac] Magnifying glass in keyword-search bubble. (Closed)
Patch Set: Present for Rohit. Created 10 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | chrome/browser/cocoa/autocomplete_text_field_cell_unittest.mm » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 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/resource_bundle.h" 7 #include "app/resource_bundle.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "gfx/font.h" 9 #include "gfx/font.h"
10 #include "grit/theme_resources.h"
10 11
11 namespace { 12 namespace {
12 13
13 const CGFloat kBaselineAdjust = 2.0; 14 const CGFloat kBaselineAdjust = 2.0;
14 15
15 // How far to offset the keyword token into the field. 16 // How far to offset the keyword token into the field.
16 const NSInteger kKeywordXOffset = 3; 17 const NSInteger kKeywordXOffset = 3;
17 18
18 // How much width (beyond text) to add to the keyword token on each 19 // How much width (beyond text) to add to the keyword token on each
19 // side. 20 // side.
20 const NSInteger kKeywordTokenInset = 3; 21 const NSInteger kKeywordTokenInset = 3;
21 22
22 // Gap to leave between hint and right-hand-side of cell. 23 // Gap to leave between hint and right-hand-side of cell.
23 const NSInteger kHintXOffset = 4; 24 const NSInteger kHintXOffset = 4;
24 25
25 // How far to shift bounding box of hint down from top of field. 26 // How far to shift bounding box of hint down from top of field.
26 // Assumes -setFlipped:YES. 27 // Assumes -setFlipped:YES.
27 const NSInteger kHintYOffset = 4; 28 const NSInteger kHintYOffset = 4;
28 29
29 // How far to inset the keywork token from sides. 30 // How far to inset the keywork token from sides.
30 const NSInteger kKeywordYInset = 4; 31 const NSInteger kKeywordYInset = 4;
31 32
32 // TODO(shess): The keyword hint image wants to sit on the baseline. 33 // TODO(shess): The keyword hint image wants to sit on the baseline.
33 // This moves it down so that there is approximately as much image 34 // This moves it down so that there is approximately as much image
34 // above the lowercase ascender as below the baseline. A better 35 // above the lowercase ascender as below the baseline. A better
35 // technique would be nice to have, though. 36 // technique would be nice to have, though.
36 const NSInteger kKeywordHintImageBaseline = -6; 37 const NSInteger kKeywordHintImageBaseline = -6;
37 38
39 // Drops the magnifying glass icon so that it looks centered in the
40 // keyword-search bubble.
41 const NSInteger kKeywordSearchImageBaseline = -4;
42
38 // The amount of padding on either side reserved for drawing an icon. 43 // The amount of padding on either side reserved for drawing an icon.
39 const NSInteger kIconHorizontalPad = 3; 44 const NSInteger kIconHorizontalPad = 3;
40 45
41 // How far to shift bounding box of hint icon label down from top of field. 46 // How far to shift bounding box of hint icon label down from top of field.
42 const NSInteger kIconLabelYOffset = 7; 47 const NSInteger kIconLabelYOffset = 7;
43 48
44 // How far the editor insets itself, for purposes of determining if 49 // How far the editor insets itself, for purposes of determining if
45 // decorations need to be trimmed. 50 // decorations need to be trimmed.
46 const CGFloat kEditorHorizontalInset = 3.0; 51 const CGFloat kEditorHorizontalInset = 3.0;
47 52
(...skipping 15 matching lines...) Expand all
63 // If there is an image, make sure we calculated the target size 68 // If there is an image, make sure we calculated the target size
64 // correctly. 69 // correctly.
65 DCHECK(!image || NSEqualSizes([image size], rect.size)); 70 DCHECK(!image || NSEqualSizes([image size], rect.size));
66 [image setFlipped:[view isFlipped]]; 71 [image setFlipped:[view isFlipped]];
67 [image drawInRect:rect 72 [image drawInRect:rect
68 fromRect:NSZeroRect // Entire image 73 fromRect:NSZeroRect // Entire image
69 operation:NSCompositeSourceOver 74 operation:NSCompositeSourceOver
70 fraction:1.0]; 75 fraction:1.0];
71 } 76 }
72 77
78 // Helper function to generate an attributed string containing
79 // |anImage|. If |baselineAdjustment| is 0, the image sits on the
80 // text baseline, positive values shift it up, negative values shift
81 // it down.
82 NSAttributedString* AttributedStringForImage(NSImage* anImage,
83 CGFloat baselineAdjustment) {
84 scoped_nsobject<NSTextAttachmentCell> attachmentCell(
85 [[NSTextAttachmentCell alloc] initImageCell:anImage]);
86 scoped_nsobject<NSTextAttachment> attachment(
87 [[NSTextAttachment alloc] init]);
88 [attachment setAttachmentCell:attachmentCell];
89
90 scoped_nsobject<NSMutableAttributedString> as(
91 [[NSAttributedString attributedStringWithAttachment:attachment]
92 mutableCopy]);
93 [as addAttribute:NSBaselineOffsetAttributeName
94 value:[NSNumber numberWithFloat:baselineAdjustment]
95 range:NSMakeRange(0, [as length])];
96
97 return [[as copy] autorelease];
98 }
99
73 } // namespace 100 } // namespace
74 101
75 @implementation AutocompleteTextFieldIcon 102 @implementation AutocompleteTextFieldIcon
76 103
77 @synthesize rect = rect_; 104 @synthesize rect = rect_;
78 @synthesize view = view_; 105 @synthesize view = view_;
79 106
80 // Private helper. 107 // Private helper.
81 - (id)initWithView:(LocationBarViewMac::LocationBarImageView*)view 108 - (id)initWithView:(LocationBarViewMac::LocationBarImageView*)view
82 isLabel:(BOOL)isLabel { 109 isLabel:(BOOL)isLabel {
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 - (void)setKeywordString:(NSString*)fullString 171 - (void)setKeywordString:(NSString*)fullString
145 partialString:(NSString*)partialString 172 partialString:(NSString*)partialString
146 availableWidth:(CGFloat)width { 173 availableWidth:(CGFloat)width {
147 DCHECK(fullString != nil); 174 DCHECK(fullString != nil);
148 175
149 hintString_.reset(); 176 hintString_.reset();
150 177
151 // Adjust for space between editor and decorations. 178 // Adjust for space between editor and decorations.
152 width -= 2 * kEditorHorizontalInset; 179 width -= 2 * kEditorHorizontalInset;
153 180
154 // If |fullString| won't fit, choose |partialString|. 181 // Get the magnifying glass to put at the front of the string.
182 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
183 NSImage* image = rb.GetNSImageNamed(IDR_O2_SEARCH);
184 const NSSize imageSize = [image size];
185
186 // Based on what fits, choose |fullString| with the image,
187 // |fullString| without the image, or |partialString|.
155 NSDictionary* attributes = 188 NSDictionary* attributes =
156 [NSDictionary dictionaryWithObject:[self font] 189 [NSDictionary dictionaryWithObject:[self font]
157 forKey:NSFontAttributeName]; 190 forKey:NSFontAttributeName];
158 NSString* s = fullString; 191 NSString* s = fullString;
159 if ([s sizeWithAttributes:attributes].width > width) { 192 const CGFloat sWidth = [s sizeWithAttributes:attributes].width;
193 if (sWidth + imageSize.width > width) {
194 image = nil;
195 }
196 if (sWidth > width) {
160 if (partialString) { 197 if (partialString) {
161 s = partialString; 198 s = partialString;
162 } 199 }
163 } 200 }
164 keywordString_.reset( 201
165 [[NSAttributedString alloc] initWithString:s attributes:attributes]); 202 scoped_nsobject<NSMutableAttributedString> as(
203 [[NSMutableAttributedString alloc] initWithString:s
204 attributes:attributes]);
205
206 // Insert the image at the front of the string if it didn't make
207 // things too wide.
208 if (image) {
209 NSAttributedString* is =
210 AttributedStringForImage(image, kKeywordSearchImageBaseline);
211 [as insertAttributedString:is atIndex:0];
212 }
213
214 keywordString_.reset([as copy]);
166 } 215 }
167 216
168 // Convenience for the attributes used in the right-justified info 217 // Convenience for the attributes used in the right-justified info
169 // cells. 218 // cells.
170 - (NSDictionary*)hintAttributes { 219 - (NSDictionary*)hintAttributes {
171 scoped_nsobject<NSMutableParagraphStyle> style( 220 scoped_nsobject<NSMutableParagraphStyle> style(
172 [[NSMutableParagraphStyle alloc] init]); 221 [[NSMutableParagraphStyle alloc] init]);
173 [style setAlignment:NSRightTextAlignment]; 222 [style setAlignment:NSRightTextAlignment];
174 223
175 return [NSDictionary dictionaryWithObjectsAndKeys: 224 return [NSDictionary dictionaryWithObjectsAndKeys:
(...skipping 27 matching lines...) Expand all
203 ![[hintString_ string] hasSuffix:suffixString]) { 252 ![[hintString_ string] hasSuffix:suffixString]) {
204 253
205 // Build an attributed string with the concatenation of the prefix 254 // Build an attributed string with the concatenation of the prefix
206 // and suffix. 255 // and suffix.
207 NSString* s = [prefixString stringByAppendingString:suffixString]; 256 NSString* s = [prefixString stringByAppendingString:suffixString];
208 scoped_nsobject<NSMutableAttributedString> as( 257 scoped_nsobject<NSMutableAttributedString> as(
209 [[NSMutableAttributedString alloc] 258 [[NSMutableAttributedString alloc]
210 initWithString:s attributes:[self hintAttributes]]); 259 initWithString:s attributes:[self hintAttributes]]);
211 260
212 // Build an attachment containing the hint image. 261 // Build an attachment containing the hint image.
213 scoped_nsobject<NSTextAttachmentCell> attachmentCell( 262 NSAttributedString* is =
214 [[NSTextAttachmentCell alloc] initImageCell:anImage]); 263 AttributedStringForImage(anImage, kKeywordHintImageBaseline);
215 scoped_nsobject<NSTextAttachment> attachment(
216 [[NSTextAttachment alloc] init]);
217 [attachment setAttachmentCell:attachmentCell];
218
219 // The attachment's baseline needs to be adjusted so the image
220 // doesn't sit on the same baseline as the text and make
221 // everything too tall.
222 scoped_nsobject<NSMutableAttributedString> is(
223 [[NSAttributedString attributedStringWithAttachment:attachment]
224 mutableCopy]);
225 [is addAttribute:NSBaselineOffsetAttributeName
226 value:[NSNumber numberWithFloat:kKeywordHintImageBaseline]
227 range:NSMakeRange(0, [is length])];
228 264
229 // Stuff the image attachment between the prefix and suffix. 265 // Stuff the image attachment between the prefix and suffix.
230 [as insertAttributedString:is atIndex:[prefixString length]]; 266 [as insertAttributedString:is atIndex:[prefixString length]];
231 267
232 // If too wide, just show the image. 268 // If too wide, just show the image.
233 hintString_.reset(WidthForHint(as) > width ? [is copy] : [as copy]); 269 hintString_.reset(WidthForHint(as) > width ? [is copy] : [as copy]);
234 } 270 }
235 } 271 }
236 272
237 - (void)setSearchHintString:(NSString*)aString 273 - (void)setSearchHintString:(NSString*)aString
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
424 [[NSColor selectedControlColor] set]; 460 [[NSColor selectedControlColor] set];
425 [path fill]; 461 [path fill];
426 462
427 // Border around token rectangle, match focus ring's inner color. 463 // Border around token rectangle, match focus ring's inner color.
428 [[[NSColor keyboardFocusIndicatorColor] colorWithAlphaComponent:0.5] set]; 464 [[[NSColor keyboardFocusIndicatorColor] colorWithAlphaComponent:0.5] set];
429 [path setLineWidth:1.0]; 465 [path setLineWidth:1.0];
430 [path stroke]; 466 [path stroke];
431 467
432 // Draw text w/in the rectangle. 468 // Draw text w/in the rectangle.
433 infoFrame.origin.x += 4.0; 469 infoFrame.origin.x += 4.0;
434 infoFrame.origin.y += 1.0;
435 [keywordString_.get() drawInRect:infoFrame]; 470 [keywordString_.get() drawInRect:infoFrame];
436 } 471 }
437 472
438 - (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView*)controlView { 473 - (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView*)controlView {
439 if (!keywordString_ && locationIconView_ && locationIconView_->IsVisible()) { 474 if (!keywordString_ && locationIconView_ && locationIconView_->IsVisible()) {
440 DrawImageInRect(locationIconView_->GetImage(), controlView, 475 DrawImageInRect(locationIconView_->GetImage(), controlView,
441 [self locationIconFrameForFrame:cellFrame]); 476 [self locationIconFrameForFrame:cellFrame]);
442 } 477 }
443 478
444 if (hintString_) { 479 if (hintString_) {
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
557 icon = [self iconForEvent:theEvent inRect:cellFrame ofView:controlView]; 592 icon = [self iconForEvent:theEvent inRect:cellFrame ofView:controlView];
558 if (icon) { 593 if (icon) {
559 [icon view]->OnMousePressed([icon rect]); 594 [icon view]->OnMousePressed([icon rect]);
560 return YES; 595 return YES;
561 } 596 }
562 597
563 return NO; 598 return NO;
564 } 599 }
565 600
566 @end 601 @end
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/cocoa/autocomplete_text_field_cell_unittest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698