diff options
author | shess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-05-11 20:39:08 +0000 |
---|---|---|
committer | shess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-05-11 20:39:08 +0000 |
commit | 56a7fbca5b93aadbfdfb0ff20a0a95ef5c91255a (patch) | |
tree | cc3993bc0ea1e2addba819d1d72d1af156405213 /chrome/browser/autocomplete | |
parent | 753abf571c333b695c3dbea83eeca55700ef4e80 (diff) | |
download | chromium_src-56a7fbca5b93aadbfdfb0ff20a0a95ef5c91255a.zip chromium_src-56a7fbca5b93aadbfdfb0ff20a0a95ef5c91255a.tar.gz chromium_src-56a7fbca5b93aadbfdfb0ff20a0a95ef5c91255a.tar.bz2 |
Style the omnibox results for v2.
The style is based on the gtk code (autocomplete_popup_view_gtk.cc), with some local tweaks. I broke this off from the rest of the review so I could experiment with making it nail omnibox-v2, but eventually realized that I don't have enough data for that. This at least makes things look nicer, and I believe it provides all of the function that will be needed (the remainder is precisely defining fonts and colors and possibly minor highlighting variations).
Summary: I want something concrete so that complaints about v2 wrongness can be specific.
Review URL: http://codereview.chromium.org/99312
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@15777 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/autocomplete')
3 files changed, 535 insertions, 12 deletions
diff --git a/chrome/browser/autocomplete/autocomplete_popup_view_mac.h b/chrome/browser/autocomplete/autocomplete_popup_view_mac.h index 858e2fe..eb00d23 100644 --- a/chrome/browser/autocomplete/autocomplete_popup_view_mac.h +++ b/chrome/browser/autocomplete/autocomplete_popup_view_mac.h @@ -70,6 +70,18 @@ class AutocompletePopupViewMac : public AutocompletePopupView { // helper object. void AcceptInput(); + // Return the text to show for the match, based on the match's + // contents and description. + static NSMutableAttributedString* MatchText(const AutocompleteMatch& match); + + // Helper for MatchText() to allow sharing code between the contents + // and description cases. Returns NSMutableAttributedString as a + // convenience for MatchText(). + static NSMutableAttributedString* DecorateMatchedString( + const std::wstring &matchString, + const AutocompleteMatch::ACMatchClassifications &classifications, + NSColor* textColor); + private: // Create the popup_ instance if needed. void CreatePopupIfNeeded(); diff --git a/chrome/browser/autocomplete/autocomplete_popup_view_mac.mm b/chrome/browser/autocomplete/autocomplete_popup_view_mac.mm index 244936b..c0a2b54 100644 --- a/chrome/browser/autocomplete/autocomplete_popup_view_mac.mm +++ b/chrome/browser/autocomplete/autocomplete_popup_view_mac.mm @@ -22,6 +22,30 @@ NSColor* HoveredBackgroundColor() { return [NSColor controlColor]; } +// TODO(shess): These are totally unprincipled. I experimented with +// +controlTextColor and the like, but found myself wondering whether +// that was really appropriate. Circle back after consulting with +// someone more knowledgeable about the ins and outs of this. +static const NSColor* ContentTextColor() { + return [NSColor blackColor]; +} +static const NSColor* URLTextColor() { + return [NSColor colorWithCalibratedRed:0.0 green:0.55 blue:0.0 alpha:1.0]; +} +static const NSColor* DescriptionTextColor() { + return [NSColor darkGrayColor]; +} + +// TODO(shess): As with colors, there are a dozen ways to phrase this, +// all of them probably wrong. Circle back with a ui-oriented +// resource later. +static const NSFont* NormalFont() { + return [NSFont userFontOfSize:12]; +} +static const NSFont* BoldFont() { + return [NSFont boldSystemFontOfSize:12]; +} + // Return the appropriate icon for the given match. Derived from the // gtk code. NSImage* MatchIcon(const AutocompleteMatch& match) { @@ -57,23 +81,86 @@ NSImage* MatchIcon(const AutocompleteMatch& match) { return nil; } -// Return the text to show for the match, based on the match's -// contents and description. -// TODO(shess): Style the runs within the text. -NSString* MatchText(const AutocompleteMatch& match) { - NSString* s = base::SysWideToNSString(match.contents); +} // namespace - if (!match.description.empty()) { - NSString* description = base::SysWideToNSString(match.description); +// Helper for MatchText() to allow sharing code between the contents +// and description cases. Returns NSMutableAttributedString as a +// convenience for MatchText(). +NSMutableAttributedString* AutocompletePopupViewMac::DecorateMatchedString( + const std::wstring &matchString, + const AutocompleteMatch::ACMatchClassifications &classifications, + NSColor* textColor) { + + // Start out with a string using the default style info. + NSString* s = base::SysWideToNSString(matchString); + NSDictionary* attributes = [NSDictionary dictionaryWithObjectsAndKeys: + NormalFont(), NSFontAttributeName, + textColor, NSForegroundColorAttributeName, + nil]; + NSMutableAttributedString* as = + [[[NSMutableAttributedString alloc] initWithString:s + attributes:attributes] + autorelease]; + + // Mark up the runs which differ from the default. + for (ACMatchClassifications::const_iterator i = classifications.begin(); + i != classifications.end(); ++i) { + const BOOL isLast = (i+1) == classifications.end(); + const size_t nextOffset = (isLast ? matchString.length() : (i+1)->offset); + const NSInteger location = static_cast<NSInteger>(i->offset); + const NSInteger length = static_cast<NSInteger>(nextOffset - i->offset); + const NSRange range = NSMakeRange(location, length); + + if (0 != (i->style & ACMatchClassification::URL)) { + [as addAttribute:NSForegroundColorAttributeName + value:URLTextColor() range:range]; + } - // Append an em dash (U-2014) and description. - s = [s stringByAppendingFormat:@" %C %@", 0x2014, description]; + if (0 != (i->style & ACMatchClassification::MATCH)) { + [as addAttribute:NSFontAttributeName value:BoldFont() range:range]; + } } - return s; + return as; } -} // namespace +// Return the text to show for the match, based on the match's +// contents and description. +NSMutableAttributedString* AutocompletePopupViewMac::MatchText( + const AutocompleteMatch& match) { + NSMutableAttributedString *as = + DecorateMatchedString(match.contents, match.contents_class, + ContentTextColor()); + + // If there is a description, append it, separated from the contents + // with an em dash, and decorated with a distinct color. + if (!match.description.empty()) { + NSDictionary* attributes = + [NSDictionary dictionaryWithObjectsAndKeys: + NormalFont(), NSFontAttributeName, + ContentTextColor(), NSForegroundColorAttributeName, + nil]; + NSString* rawEmDash = [NSString stringWithFormat:@" %C ", 0x2014]; + NSAttributedString* emDash = + [[[NSAttributedString alloc] initWithString:rawEmDash + attributes:attributes] autorelease]; + + NSAttributedString* description = + DecorateMatchedString(match.description, match.description_class, + DescriptionTextColor()); + + [as appendAttributedString:emDash]; + [as appendAttributedString:description]; + } + + NSMutableParagraphStyle* style = + [[[NSMutableParagraphStyle alloc] init] autorelease]; + [style setLineBreakMode:NSLineBreakByTruncatingTail]; + [as addAttribute:NSParagraphStyleAttributeName value:style + range:NSMakeRange(0, [as length])]; + + return as; +} // AutocompleteButtonCell overrides how backgrounds are displayed to // handle hover versus selected. So long as we're in there, it also @@ -199,7 +286,7 @@ void AutocompletePopupViewMac::UpdatePopupAppearance() { AutocompleteButtonCell* cell = [matrix cellAtRow:ii column:0]; const AutocompleteMatch& match = model_->result().match_at(ii); [cell setImage:MatchIcon(match)]; - [cell setTitle:MatchText(match)]; + [cell setAttributedTitle:MatchText(match)]; } // Update the selection. diff --git a/chrome/browser/autocomplete/autocomplete_popup_view_mac_unittest.mm b/chrome/browser/autocomplete/autocomplete_popup_view_mac_unittest.mm new file mode 100644 index 0000000..059a5e1 --- /dev/null +++ b/chrome/browser/autocomplete/autocomplete_popup_view_mac_unittest.mm @@ -0,0 +1,424 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "chrome/browser/autocomplete/autocomplete_popup_view_mac.h" + +#include "base/sys_string_conversions.h" +#include "chrome/browser/autocomplete/autocomplete.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +class AutocompletePopupViewMacTest : public testing::Test { + public: + AutocompletePopupViewMacTest() { + } + + // Returns the length of the run starting at |location| for which + // |attributeName| remains the same. + static NSUInteger RunLengthForAttribute(NSAttributedString* string, + NSUInteger location, + NSString* attributeName) { + const NSRange fullRange = NSMakeRange(0, [string length]); + NSRange range; + [string attribute:attributeName + atIndex:location longestEffectiveRange:&range inRange:fullRange]; + + // In order to signal when the run doesn't start exactly at + // location, return a weirdo length. This causes the incorrect + // expectation to manifest at the calling location, which is more + // useful than an EXPECT_EQ() would be here. + if (range.location != location) { + return -1; + } + + return range.length; + } + + // Return true if the run starting at |location| has |color| for + // attribute NSForegroundColorAttributeName. + static bool RunHasColor(NSAttributedString* string, + NSUInteger location, NSColor* color) { + const NSRange fullRange = NSMakeRange(0, [string length]); + NSRange range; + NSColor* runColor = [string attribute:NSForegroundColorAttributeName + atIndex:location + longestEffectiveRange:&range inRange:fullRange]; + + // According to one "Ali Ozer", you can compare objects within the + // same color space using -isEqual:. Converting color spaces + // seems too heavyweight for these tests. + // http://lists.apple.com/archives/cocoa-dev/2005/May/msg00186.html + return [runColor isEqual:color] ? true : false; + } + + // Return true if the run starting at |location| has the font + // trait(s) in |mask| font in NSFontAttributeName. + static bool RunHasFontTrait(NSAttributedString* string, NSUInteger location, + NSFontTraitMask mask) { + const NSRange fullRange = NSMakeRange(0, [string length]); + NSRange range; + NSFont* runFont = [string attribute:NSFontAttributeName + atIndex:location + longestEffectiveRange:&range inRange:fullRange]; + NSFontManager* fontManager = [NSFontManager sharedFontManager]; + if (runFont && (mask == ([fontManager traitsOfFont:runFont]&mask))) { + return true; + } + return false; + } + + // AutocompleteMatch doesn't really have the right constructor for our + // needs. Fake one for us to use. + static AutocompleteMatch MakeMatch(const std::wstring &contents, + const std::wstring &description) { + AutocompleteMatch m(NULL, 1, true, AutocompleteMatch::URL_WHAT_YOU_TYPED); + m.contents = contents; + m.description = description; + return m; + } + +}; + +// Simple inputs with no matches should result in styled output who's +// text matches the input string, with the passed-in color, and +// nothing bolded. +TEST_F(AutocompletePopupViewMacTest, DecorateMatchedStringNoMatch) { + const NSString* string = @"This is a test"; + AutocompleteMatch::ACMatchClassifications classifications; + + NSAttributedString* decorated = + AutocompletePopupViewMac::DecorateMatchedString( + base::SysNSStringToWide(string), classifications, + [NSColor blackColor]); + + // Result has same characters as the input. + EXPECT_EQ([decorated length], [string length]); + EXPECT_TRUE([[decorated string] isEqualToString:string]); + + // Our passed-in color for the entire string. + EXPECT_EQ(RunLengthForAttribute(decorated, 0U, + NSForegroundColorAttributeName), + [string length]); + EXPECT_TRUE(RunHasColor(decorated, 0U, [NSColor blackColor])); + + // An unbolded font for the entire string. + EXPECT_EQ(RunLengthForAttribute(decorated, 0U, + NSFontAttributeName), [string length]); + EXPECT_FALSE(RunHasFontTrait(decorated, 0U, NSBoldFontMask)); +} + +// Identical to DecorateMatchedStringNoMatch, except test that URL +// style gets a different color than we passed in. +TEST_F(AutocompletePopupViewMacTest, DecorateMatchedStringURLNoMatch) { + const NSString* string = @"This is a test"; + AutocompleteMatch::ACMatchClassifications classifications; + + classifications.push_back( + ACMatchClassification(0, ACMatchClassification::URL)); + + NSAttributedString* decorated = + AutocompletePopupViewMac::DecorateMatchedString( + base::SysNSStringToWide(string), classifications, + [NSColor blackColor]); + + // Result has same characters as the input. + EXPECT_EQ([decorated length], [string length]); + EXPECT_TRUE([[decorated string] isEqualToString:string]); + + // One color for the entire string, and it's not the one we passed in. + EXPECT_EQ(RunLengthForAttribute(decorated, 0U, + NSForegroundColorAttributeName), + [string length]); + EXPECT_FALSE(RunHasColor(decorated, 0U, [NSColor blackColor])); + + // An unbolded font for the entire string. + EXPECT_EQ(RunLengthForAttribute(decorated, 0U, + NSFontAttributeName), [string length]); + EXPECT_FALSE(RunHasFontTrait(decorated, 0U, NSBoldFontMask)); +} + +// Test that DIM doesn't have any impact - true at this time. +TEST_F(AutocompletePopupViewMacTest, DecorateMatchedStringDimNoMatch) { + const NSString* string = @"This is a test"; + + // Switch to DIM halfway through. + AutocompleteMatch::ACMatchClassifications classifications; + classifications.push_back( + ACMatchClassification(0, ACMatchClassification::NONE)); + classifications.push_back( + ACMatchClassification([string length] / 2, ACMatchClassification::DIM)); + + NSAttributedString* decorated = + AutocompletePopupViewMac::DecorateMatchedString( + base::SysNSStringToWide(string), classifications, + [NSColor blackColor]); + + // Result has same characters as the input. + EXPECT_EQ([decorated length], [string length]); + EXPECT_TRUE([[decorated string] isEqualToString:string]); + + // Our passed-in color for the entire string. + EXPECT_EQ(RunLengthForAttribute(decorated, 0U, + NSForegroundColorAttributeName), + [string length]); + EXPECT_TRUE(RunHasColor(decorated, 0U, [NSColor blackColor])); + + // An unbolded font for the entire string. + EXPECT_EQ(RunLengthForAttribute(decorated, 0U, + NSFontAttributeName), [string length]); + EXPECT_FALSE(RunHasFontTrait(decorated, 0U, NSBoldFontMask)); +} + +// Test that the matched run gets bold-faced, but keeps the same +// color. +TEST_F(AutocompletePopupViewMacTest, DecorateMatchedStringMatch) { + const NSString* string = @"This is a test"; + // Match "is". + const NSUInteger runLength1 = 5, runLength2 = 2, runLength3 = 7; + // Make sure nobody messed up the inputs. + EXPECT_EQ(runLength1 + runLength2 + runLength3, [string length]); + + // Push each run onto classifications. + AutocompleteMatch::ACMatchClassifications classifications; + classifications.push_back( + ACMatchClassification(0, ACMatchClassification::NONE)); + classifications.push_back( + ACMatchClassification(runLength1, ACMatchClassification::MATCH)); + classifications.push_back( + ACMatchClassification(runLength1 + runLength2, + ACMatchClassification::NONE)); + + NSAttributedString* decorated = + AutocompletePopupViewMac::DecorateMatchedString( + base::SysNSStringToWide(string), classifications, + [NSColor blackColor]); + + // Result has same characters as the input. + EXPECT_EQ([decorated length], [string length]); + EXPECT_TRUE([[decorated string] isEqualToString:string]); + + // Our passed-in color for the entire string. + EXPECT_EQ(RunLengthForAttribute(decorated, 0U, + NSForegroundColorAttributeName), + [string length]); + EXPECT_TRUE(RunHasColor(decorated, 0U, [NSColor blackColor])); + + // Should have three font runs, not bold, bold, then not bold again. + EXPECT_EQ(RunLengthForAttribute(decorated, 0U, + NSFontAttributeName), runLength1); + EXPECT_FALSE(RunHasFontTrait(decorated, 0U, NSBoldFontMask)); + + EXPECT_EQ(RunLengthForAttribute(decorated, runLength1, + NSFontAttributeName), runLength2); + EXPECT_TRUE(RunHasFontTrait(decorated, runLength1, NSBoldFontMask)); + + EXPECT_EQ(RunLengthForAttribute(decorated, runLength1 + runLength2, + NSFontAttributeName), runLength3); + EXPECT_FALSE(RunHasFontTrait(decorated, runLength1 + runLength2, + NSBoldFontMask)); +} + +// Just like DecorateMatchedStringURLMatch, this time with URL style. +TEST_F(AutocompletePopupViewMacTest, DecorateMatchedStringURLMatch) { + const NSString* string = @"http://hello.world/"; + // Match "hello". + const NSUInteger runLength1 = 7, runLength2 = 5, runLength3 = 7; + // Make sure nobody messed up the inputs. + EXPECT_EQ(runLength1 + runLength2 + runLength3, [string length]); + + // Push each run onto classifications. + AutocompleteMatch::ACMatchClassifications classifications; + classifications.push_back( + ACMatchClassification(0, ACMatchClassification::URL)); + const int kURLMatch = ACMatchClassification::URL|ACMatchClassification::MATCH; + classifications.push_back(ACMatchClassification(runLength1, kURLMatch)); + classifications.push_back( + ACMatchClassification(runLength1 + runLength2, + ACMatchClassification::URL)); + + NSAttributedString* decorated = + AutocompletePopupViewMac::DecorateMatchedString( + base::SysNSStringToWide(string), classifications, + [NSColor blackColor]); + + // Result has same characters as the input. + EXPECT_EQ([decorated length], [string length]); + EXPECT_TRUE([[decorated string] isEqualToString:string]); + + // One color for the entire string, and it's not the one we passed in. + EXPECT_EQ(RunLengthForAttribute(decorated, 0U, + NSForegroundColorAttributeName), + [string length]); + EXPECT_FALSE(RunHasColor(decorated, 0U, [NSColor blackColor])); + + // Should have three font runs, not bold, bold, then not bold again. + EXPECT_EQ(RunLengthForAttribute(decorated, 0U, + NSFontAttributeName), runLength1); + EXPECT_FALSE(RunHasFontTrait(decorated, 0U, NSBoldFontMask)); + + EXPECT_EQ(RunLengthForAttribute(decorated, runLength1, + NSFontAttributeName), runLength2); + EXPECT_TRUE(RunHasFontTrait(decorated, runLength1, NSBoldFontMask)); + + EXPECT_EQ(RunLengthForAttribute(decorated, runLength1 + runLength2, + NSFontAttributeName), runLength3); + EXPECT_FALSE(RunHasFontTrait(decorated, runLength1 + runLength2, + NSBoldFontMask)); +} + +// Check that matches with both contents and description come back +// with contents at the beginning, description at the end, and +// something separating them. Not being specific about the separator +// on purpose, in case it changes. +TEST_F(AutocompletePopupViewMacTest, MatchText) { + const NSString* contents = @"contents"; + const NSString* description = @"description"; + AutocompleteMatch m = MakeMatch(base::SysNSStringToWide(contents), + base::SysNSStringToWide(description)); + + NSAttributedString* decorated = AutocompletePopupViewMac::MatchText(m); + + // Result contains the characters of the input in the right places. + EXPECT_GT([decorated length], [contents length] + [description length]); + EXPECT_TRUE([[decorated string] hasPrefix:contents]); + EXPECT_TRUE([[decorated string] hasSuffix:description]); + + // Check that the description is a different color from the + // contents. + const NSUInteger descriptionLocation = + [decorated length] - [description length]; + EXPECT_EQ(RunLengthForAttribute(decorated, 0U, + NSForegroundColorAttributeName), + descriptionLocation); + EXPECT_EQ(RunLengthForAttribute(decorated, descriptionLocation, + NSForegroundColorAttributeName), + [description length]); + + // Same font all the way through, nothing bold. + EXPECT_EQ(RunLengthForAttribute(decorated, 0U, + NSFontAttributeName), [decorated length]); + EXPECT_FALSE(RunHasFontTrait(decorated, 0, NSBoldFontMask)); +} + +// Check that MatchText() styles content matches as expected. +TEST_F(AutocompletePopupViewMacTest, MatchTextContentsMatch) { + const NSString* contents = @"This is a test"; + // Match "is". + const NSUInteger runLength1 = 5, runLength2 = 2, runLength3 = 7; + // Make sure nobody messed up the inputs. + EXPECT_EQ(runLength1 + runLength2 + runLength3, [contents length]); + + AutocompleteMatch m = MakeMatch(base::SysNSStringToWide(contents), + std::wstring()); + + // Push each run onto contents classifications. + m.contents_class.push_back( + ACMatchClassification(0, ACMatchClassification::NONE)); + m.contents_class.push_back( + ACMatchClassification(runLength1, ACMatchClassification::MATCH)); + m.contents_class.push_back( + ACMatchClassification(runLength1 + runLength2, + ACMatchClassification::NONE)); + + NSAttributedString* decorated = AutocompletePopupViewMac::MatchText(m); + + // Result has same characters as the input. + EXPECT_EQ([decorated length], [contents length]); + EXPECT_TRUE([[decorated string] isEqualToString:contents]); + + // Result is all one color. + EXPECT_EQ(RunLengthForAttribute(decorated, 0U, + NSForegroundColorAttributeName), + [contents length]); + + // Should have three font runs, not bold, bold, then not bold again. + EXPECT_EQ(RunLengthForAttribute(decorated, 0U, + NSFontAttributeName), runLength1); + EXPECT_FALSE(RunHasFontTrait(decorated, 0U, NSBoldFontMask)); + + EXPECT_EQ(RunLengthForAttribute(decorated, runLength1, + NSFontAttributeName), runLength2); + EXPECT_TRUE(RunHasFontTrait(decorated, runLength1, NSBoldFontMask)); + + EXPECT_EQ(RunLengthForAttribute(decorated, runLength1 + runLength2, + NSFontAttributeName), runLength3); + EXPECT_FALSE(RunHasFontTrait(decorated, runLength1 + runLength2, + NSBoldFontMask)); +} + +// Check that MatchText() styles description matches as expected. +TEST_F(AutocompletePopupViewMacTest, MatchTextDescriptionMatch) { + const NSString* contents = @"This is a test"; + const NSString* description = @"That was a test"; + // Match "That was". + const NSUInteger runLength1 = 8, runLength2 = 7; + // Make sure nobody messed up the inputs. + EXPECT_EQ(runLength1 + runLength2, [description length]); + + AutocompleteMatch m = MakeMatch(base::SysNSStringToWide(contents), + base::SysNSStringToWide(description)); + + // Push each run onto contents classifications. + m.description_class.push_back( + ACMatchClassification(0, ACMatchClassification::MATCH)); + m.description_class.push_back( + ACMatchClassification(runLength1, ACMatchClassification::NONE)); + + NSAttributedString* decorated = AutocompletePopupViewMac::MatchText(m); + + // Result contains the characters of the input. + EXPECT_GT([decorated length], [contents length] + [description length]); + EXPECT_TRUE([[decorated string] hasPrefix:contents]); + EXPECT_TRUE([[decorated string] hasSuffix:description]); + + // Check that the description is a different color from the + // contents. + const NSUInteger descriptionLocation = + [decorated length] - [description length]; + EXPECT_EQ(RunLengthForAttribute(decorated, 0U, + NSForegroundColorAttributeName), + descriptionLocation); + EXPECT_EQ(RunLengthForAttribute(decorated, descriptionLocation, + NSForegroundColorAttributeName), + [description length]); + + // Should have three font runs, not bold, bold, then not bold again. + // The first run is the contents and the separator, the second run + // is the first run of the description. + EXPECT_EQ(RunLengthForAttribute(decorated, 0U, + NSFontAttributeName), descriptionLocation); + EXPECT_FALSE(RunHasFontTrait(decorated, 0U, NSBoldFontMask)); + + EXPECT_EQ(RunLengthForAttribute(decorated, descriptionLocation, + NSFontAttributeName), runLength1); + EXPECT_TRUE(RunHasFontTrait(decorated, descriptionLocation, NSBoldFontMask)); + + EXPECT_EQ(RunLengthForAttribute(decorated, descriptionLocation + runLength1, + NSFontAttributeName), runLength2); + EXPECT_FALSE(RunHasFontTrait(decorated, descriptionLocation + runLength1, + NSBoldFontMask)); +} + +// TODO(shess): Test that +// AutocompletePopupViewMac::UpdatePopupAppearance() creates/destroys +// the popup according to result contents. Test that the matrix gets +// the right number of results. Test the contents of the cells for +// the right strings. Icons? Maybe, that seems harder to test. +// Styling seems almost impossible. + +// TODO(shess): Test that AutocompletePopupViewMac::PaintUpdatesNow() +// updates the matrix selection. + +// TODO(shess): Test that AutocompletePopupViewMac::AcceptInput() +// updates the model's selection from the matrix before returning. +// Could possibly test that via -select:. + +// TODO(shess): Test that AutocompleteButtonCell returns the right +// background colors for on, highlighted, and neither. + +// TODO(shess): Test that AutocompleteMatrixTarget can be initialized +// and then sends -select: to the view. + +} // namespace |