diff options
author | shess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-04-02 22:39:50 +0000 |
---|---|---|
committer | shess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-04-02 22:39:50 +0000 |
commit | 72acf913daa9cbdaeb193a02c5b5958be97bbd28 (patch) | |
tree | e48becbb2a1939760798017a5084b964374f58d9 | |
parent | 4e1d0347528d3be39ff4854a1b9268accb001282 (diff) | |
download | chromium_src-72acf913daa9cbdaeb193a02c5b5958be97bbd28.zip chromium_src-72acf913daa9cbdaeb193a02c5b5958be97bbd28.tar.gz chromium_src-72acf913daa9cbdaeb193a02c5b5958be97bbd28.tar.bz2 |
[Mac] Magnifying glass in keyword-search bubble.
Abstract the image-in-attributed-string code into a helper function so
everyone makes the same mistakes. The keyword-search string's
baseline became wrong at some point, adjust it to match the rest of
the field.
BUG=37865
TEST=Type "google.com" until "press tab to search" appears, hit TAB. "Search Google:" bubble should have a magnifying glass on the LHS.
TEST=Add a bunch of text to search. Resizing smaller should first remove the image, then change to shorter text ("Search Go..." or somesuch).
Review URL: http://codereview.chromium.org/1581011
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@43540 0039d316-1c4b-4281-b951-d872f2087c98
3 files changed, 69 insertions, 23 deletions
diff --git a/chrome/browser/cocoa/autocomplete_text_field_cell.mm b/chrome/browser/cocoa/autocomplete_text_field_cell.mm index 699a59b..9e5fbe5 100644 --- a/chrome/browser/cocoa/autocomplete_text_field_cell.mm +++ b/chrome/browser/cocoa/autocomplete_text_field_cell.mm @@ -7,6 +7,7 @@ #include "app/resource_bundle.h" #include "base/logging.h" #include "gfx/font.h" +#include "grit/theme_resources.h" namespace { @@ -35,6 +36,10 @@ const NSInteger kKeywordYInset = 4; // technique would be nice to have, though. const NSInteger kKeywordHintImageBaseline = -6; +// Drops the magnifying glass icon so that it looks centered in the +// keyword-search bubble. +const NSInteger kKeywordSearchImageBaseline = -4; + // The amount of padding on either side reserved for drawing an icon. const NSInteger kIconHorizontalPad = 3; @@ -70,6 +75,28 @@ void DrawImageInRect(NSImage* image, NSView* view, const NSRect& rect) { fraction:1.0]; } +// Helper function to generate an attributed string containing +// |anImage|. If |baselineAdjustment| is 0, the image sits on the +// text baseline, positive values shift it up, negative values shift +// it down. +NSAttributedString* AttributedStringForImage(NSImage* anImage, + CGFloat baselineAdjustment) { + scoped_nsobject<NSTextAttachmentCell> attachmentCell( + [[NSTextAttachmentCell alloc] initImageCell:anImage]); + scoped_nsobject<NSTextAttachment> attachment( + [[NSTextAttachment alloc] init]); + [attachment setAttachmentCell:attachmentCell]; + + scoped_nsobject<NSMutableAttributedString> as( + [[NSAttributedString attributedStringWithAttachment:attachment] + mutableCopy]); + [as addAttribute:NSBaselineOffsetAttributeName + value:[NSNumber numberWithFloat:baselineAdjustment] + range:NSMakeRange(0, [as length])]; + + return [[as copy] autorelease]; +} + } // namespace @implementation AutocompleteTextFieldIcon @@ -151,18 +178,40 @@ void DrawImageInRect(NSImage* image, NSView* view, const NSRect& rect) { // Adjust for space between editor and decorations. width -= 2 * kEditorHorizontalInset; - // If |fullString| won't fit, choose |partialString|. + // Get the magnifying glass to put at the front of the string. + ResourceBundle& rb = ResourceBundle::GetSharedInstance(); + NSImage* image = rb.GetNSImageNamed(IDR_O2_SEARCH); + const NSSize imageSize = [image size]; + + // Based on what fits, choose |fullString| with the image, + // |fullString| without the image, or |partialString|. NSDictionary* attributes = [NSDictionary dictionaryWithObject:[self font] forKey:NSFontAttributeName]; NSString* s = fullString; - if ([s sizeWithAttributes:attributes].width > width) { + const CGFloat sWidth = [s sizeWithAttributes:attributes].width; + if (sWidth + imageSize.width > width) { + image = nil; + } + if (sWidth > width) { if (partialString) { s = partialString; } } - keywordString_.reset( - [[NSAttributedString alloc] initWithString:s attributes:attributes]); + + scoped_nsobject<NSMutableAttributedString> as( + [[NSMutableAttributedString alloc] initWithString:s + attributes:attributes]); + + // Insert the image at the front of the string if it didn't make + // things too wide. + if (image) { + NSAttributedString* is = + AttributedStringForImage(image, kKeywordSearchImageBaseline); + [as insertAttributedString:is atIndex:0]; + } + + keywordString_.reset([as copy]); } // Convenience for the attributes used in the right-justified info @@ -210,21 +259,8 @@ void DrawImageInRect(NSImage* image, NSView* view, const NSRect& rect) { initWithString:s attributes:[self hintAttributes]]); // Build an attachment containing the hint image. - scoped_nsobject<NSTextAttachmentCell> attachmentCell( - [[NSTextAttachmentCell alloc] initImageCell:anImage]); - scoped_nsobject<NSTextAttachment> attachment( - [[NSTextAttachment alloc] init]); - [attachment setAttachmentCell:attachmentCell]; - - // The attachment's baseline needs to be adjusted so the image - // doesn't sit on the same baseline as the text and make - // everything too tall. - scoped_nsobject<NSMutableAttributedString> is( - [[NSAttributedString attributedStringWithAttachment:attachment] - mutableCopy]); - [is addAttribute:NSBaselineOffsetAttributeName - value:[NSNumber numberWithFloat:kKeywordHintImageBaseline] - range:NSMakeRange(0, [is length])]; + NSAttributedString* is = + AttributedStringForImage(anImage, kKeywordHintImageBaseline); // Stuff the image attachment between the prefix and suffix. [as insertAttributedString:is atIndex:[prefixString length]]; @@ -431,7 +467,6 @@ void DrawImageInRect(NSImage* image, NSView* view, const NSRect& rect) { // Draw text w/in the rectangle. infoFrame.origin.x += 4.0; - infoFrame.origin.y += 1.0; [keywordString_.get() drawInRect:infoFrame]; } diff --git a/chrome/browser/cocoa/autocomplete_text_field_cell_unittest.mm b/chrome/browser/cocoa/autocomplete_text_field_cell_unittest.mm index 65241db8..00e7b62 100644 --- a/chrome/browser/cocoa/autocomplete_text_field_cell_unittest.mm +++ b/chrome/browser/cocoa/autocomplete_text_field_cell_unittest.mm @@ -443,11 +443,22 @@ TEST_F(AutocompleteTextFieldCellTest, UsesPartialKeywordIfNarrow) { const NSString* kFullString = @"Search Engine:"; const NSString* kPartialString = @"Search Eng:"; - // Wide width chooses the full string. + // Wide width chooses the full string, including an image on the + // left. [cell setKeywordString:kFullString partialString:kPartialString availableWidth:kWidth]; EXPECT_TRUE([cell keywordString]); + EXPECT_TRUE([[[cell keywordString] string] hasSuffix:kFullString]); + EXPECT_TRUE([[cell keywordString] containsAttachments]); + + // If not enough space to include the image, uses exactly the full + // string. + CGFloat allWidth = [[cell keywordString] size].width; + [cell setKeywordString:kFullString + partialString:kPartialString + availableWidth:allWidth - 5.0]; + EXPECT_TRUE([cell keywordString]); EXPECT_TRUE([[[cell keywordString] string] isEqualToString:kFullString]); // Narrow width chooses the partial string. diff --git a/chrome/browser/cocoa/location_bar_view_mac_unittest.mm b/chrome/browser/cocoa/location_bar_view_mac_unittest.mm index aec948d..733b6619 100644 --- a/chrome/browser/cocoa/location_bar_view_mac_unittest.mm +++ b/chrome/browser/cocoa/location_bar_view_mac_unittest.mm @@ -118,11 +118,11 @@ TEST_F(LocationBarViewMacTest, OnChangedImpl) { // parameter is true or false. LocationBarViewMac::OnChangedImpl( field_, kKeyword, kKeyword, false, true, image); - EXPECT_TRUE([[[cell keywordString] string] isEqualToString:kKeywordString]); + EXPECT_TRUE([[[cell keywordString] string] hasSuffix:kKeywordString]); EXPECT_FALSE([cell hintString]); LocationBarViewMac::OnChangedImpl( field_, kKeyword, kKeyword, false, false, image); - EXPECT_TRUE([[[cell keywordString] string] isEqualToString:kKeywordString]); + EXPECT_TRUE([[[cell keywordString] string] hasSuffix:kKeywordString]); EXPECT_FALSE([cell hintString]); // Check that a partial keyword-search string is passed down in case |