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

Side by Side Diff: chrome/browser/autocomplete/autocomplete_popup_view_mac.mm

Issue 115334: Use the Mac omnibox field's font as the basis for the fonts used in the field and popup. (Closed)
Patch Set: Address Pink's comments. Created 11 years, 7 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
OLDNEW
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 #include "chrome/browser/autocomplete/autocomplete_popup_view_mac.h" 5 #include "chrome/browser/autocomplete/autocomplete_popup_view_mac.h"
6 6
7 #include "base/sys_string_conversions.h" 7 #include "base/sys_string_conversions.h"
8 #include "chrome/browser/autocomplete/autocomplete_edit.h" 8 #include "chrome/browser/autocomplete/autocomplete_edit.h"
9 #include "chrome/browser/autocomplete/autocomplete_edit_view_mac.h" 9 #include "chrome/browser/autocomplete/autocomplete_edit_view_mac.h"
10 #include "chrome/browser/autocomplete/autocomplete_popup_model.h" 10 #include "chrome/browser/autocomplete/autocomplete_popup_model.h"
(...skipping 18 matching lines...) Expand all
29 static const NSColor* ContentTextColor() { 29 static const NSColor* ContentTextColor() {
30 return [NSColor blackColor]; 30 return [NSColor blackColor];
31 } 31 }
32 static const NSColor* URLTextColor() { 32 static const NSColor* URLTextColor() {
33 return [NSColor colorWithCalibratedRed:0.0 green:0.55 blue:0.0 alpha:1.0]; 33 return [NSColor colorWithCalibratedRed:0.0 green:0.55 blue:0.0 alpha:1.0];
34 } 34 }
35 static const NSColor* DescriptionTextColor() { 35 static const NSColor* DescriptionTextColor() {
36 return [NSColor darkGrayColor]; 36 return [NSColor darkGrayColor];
37 } 37 }
38 38
39 // TODO(shess): As with colors, there are a dozen ways to phrase this,
40 // all of them probably wrong. Circle back with a ui-oriented
41 // resource later.
42 static const NSFont* NormalFont() {
43 return [NSFont userFontOfSize:12];
44 }
45 static const NSFont* BoldFont() {
46 return [NSFont boldSystemFontOfSize:12];
47 }
48
49 // Return the appropriate icon for the given match. Derived from the 39 // Return the appropriate icon for the given match. Derived from the
50 // gtk code. 40 // gtk code.
51 NSImage* MatchIcon(const AutocompleteMatch& match) { 41 NSImage* MatchIcon(const AutocompleteMatch& match) {
52 if (match.starred) { 42 if (match.starred) {
53 return [NSImage imageNamed:@"o2_star.png"]; 43 return [NSImage imageNamed:@"o2_star.png"];
54 } 44 }
55 45
56 switch (match.type) { 46 switch (match.type) {
57 case AutocompleteMatch::URL_WHAT_YOU_TYPED: 47 case AutocompleteMatch::URL_WHAT_YOU_TYPED:
58 case AutocompleteMatch::NAVSUGGEST: { 48 case AutocompleteMatch::NAVSUGGEST: {
(...skipping 23 matching lines...) Expand all
82 } 72 }
83 73
84 } // namespace 74 } // namespace
85 75
86 // Helper for MatchText() to allow sharing code between the contents 76 // Helper for MatchText() to allow sharing code between the contents
87 // and description cases. Returns NSMutableAttributedString as a 77 // and description cases. Returns NSMutableAttributedString as a
88 // convenience for MatchText(). 78 // convenience for MatchText().
89 NSMutableAttributedString* AutocompletePopupViewMac::DecorateMatchedString( 79 NSMutableAttributedString* AutocompletePopupViewMac::DecorateMatchedString(
90 const std::wstring &matchString, 80 const std::wstring &matchString,
91 const AutocompleteMatch::ACMatchClassifications &classifications, 81 const AutocompleteMatch::ACMatchClassifications &classifications,
92 NSColor* textColor) { 82 NSColor* textColor, NSFont* font) {
83 // Cache for on-demand computation of the bold version of |font|.
84 NSFont* boldFont = nil;
93 85
94 // Start out with a string using the default style info. 86 // Start out with a string using the default style info.
95 NSString* s = base::SysWideToNSString(matchString); 87 NSString* s = base::SysWideToNSString(matchString);
96 NSDictionary* attributes = [NSDictionary dictionaryWithObjectsAndKeys: 88 NSDictionary* attributes = [NSDictionary dictionaryWithObjectsAndKeys:
97 NormalFont(), NSFontAttributeName, 89 font, NSFontAttributeName,
98 textColor, NSForegroundColorAttributeName, 90 textColor, NSForegroundColorAttributeName,
99 nil]; 91 nil];
100 NSMutableAttributedString* as = 92 NSMutableAttributedString* as =
101 [[[NSMutableAttributedString alloc] initWithString:s 93 [[[NSMutableAttributedString alloc] initWithString:s
102 attributes:attributes] 94 attributes:attributes]
103 autorelease]; 95 autorelease];
104 96
105 // Mark up the runs which differ from the default. 97 // Mark up the runs which differ from the default.
106 for (ACMatchClassifications::const_iterator i = classifications.begin(); 98 for (ACMatchClassifications::const_iterator i = classifications.begin();
107 i != classifications.end(); ++i) { 99 i != classifications.end(); ++i) {
108 const BOOL isLast = (i+1) == classifications.end(); 100 const BOOL isLast = (i+1) == classifications.end();
109 const size_t nextOffset = (isLast ? matchString.length() : (i+1)->offset); 101 const size_t nextOffset = (isLast ? matchString.length() : (i+1)->offset);
110 const NSInteger location = static_cast<NSInteger>(i->offset); 102 const NSInteger location = static_cast<NSInteger>(i->offset);
111 const NSInteger length = static_cast<NSInteger>(nextOffset - i->offset); 103 const NSInteger length = static_cast<NSInteger>(nextOffset - i->offset);
112 const NSRange range = NSMakeRange(location, length); 104 const NSRange range = NSMakeRange(location, length);
113 105
114 if (0 != (i->style & ACMatchClassification::URL)) { 106 if (0 != (i->style & ACMatchClassification::URL)) {
115 [as addAttribute:NSForegroundColorAttributeName 107 [as addAttribute:NSForegroundColorAttributeName
116 value:URLTextColor() range:range]; 108 value:URLTextColor() range:range];
117 } 109 }
118 110
119 if (0 != (i->style & ACMatchClassification::MATCH)) { 111 if (0 != (i->style & ACMatchClassification::MATCH)) {
120 [as addAttribute:NSFontAttributeName value:BoldFont() range:range]; 112 if (!boldFont) {
113 NSFontManager* fontManager = [NSFontManager sharedFontManager];
114 boldFont = [fontManager convertFont:font toHaveTrait:NSBoldFontMask];
115 }
116 [as addAttribute:NSFontAttributeName value:boldFont range:range];
121 } 117 }
122 } 118 }
123 119
124 return as; 120 return as;
125 } 121 }
126 122
127 // Return the text to show for the match, based on the match's 123 // Return the text to show for the match, based on the match's
128 // contents and description. 124 // contents and description. Result will be in |font|, with the
129 NSMutableAttributedString* AutocompletePopupViewMac::MatchText( 125 // boldfaced version used for matches.
130 const AutocompleteMatch& match) { 126 NSAttributedString* AutocompletePopupViewMac::MatchText(
127 const AutocompleteMatch& match, NSFont* font) {
131 NSMutableAttributedString *as = 128 NSMutableAttributedString *as =
132 DecorateMatchedString(match.contents, match.contents_class, 129 DecorateMatchedString(match.contents, match.contents_class,
133 ContentTextColor()); 130 ContentTextColor(), font);
134 131
135 // If there is a description, append it, separated from the contents 132 // If there is a description, append it, separated from the contents
136 // with an em dash, and decorated with a distinct color. 133 // with an em dash, and decorated with a distinct color.
137 if (!match.description.empty()) { 134 if (!match.description.empty()) {
138 NSDictionary* attributes = 135 NSDictionary* attributes =
139 [NSDictionary dictionaryWithObjectsAndKeys: 136 [NSDictionary dictionaryWithObjectsAndKeys:
140 NormalFont(), NSFontAttributeName, 137 font, NSFontAttributeName,
141 ContentTextColor(), NSForegroundColorAttributeName, 138 ContentTextColor(), NSForegroundColorAttributeName,
142 nil]; 139 nil];
143 NSString* rawEmDash = [NSString stringWithFormat:@" %C ", 0x2014]; 140 NSString* rawEmDash = [NSString stringWithFormat:@" %C ", 0x2014];
144 NSAttributedString* emDash = 141 NSAttributedString* emDash =
145 [[[NSAttributedString alloc] initWithString:rawEmDash 142 [[[NSAttributedString alloc] initWithString:rawEmDash
146 attributes:attributes] autorelease]; 143 attributes:attributes] autorelease];
147 144
148 NSAttributedString* description = 145 NSAttributedString* description =
149 DecorateMatchedString(match.description, match.description_class, 146 DecorateMatchedString(match.description, match.description_class,
150 DescriptionTextColor()); 147 DescriptionTextColor(), font);
151 148
152 [as appendAttributedString:emDash]; 149 [as appendAttributedString:emDash];
153 [as appendAttributedString:description]; 150 [as appendAttributedString:description];
154 } 151 }
155 152
156 NSMutableParagraphStyle* style = 153 NSMutableParagraphStyle* style =
157 [[[NSMutableParagraphStyle alloc] init] autorelease]; 154 [[[NSMutableParagraphStyle alloc] init] autorelease];
158 [style setLineBreakMode:NSLineBreakByTruncatingTail]; 155 [style setLineBreakMode:NSLineBreakByTruncatingTail];
159 [as addAttribute:NSParagraphStyleAttributeName value:style 156 [as addAttribute:NSParagraphStyleAttributeName value:style
160 range:NSMakeRange(0, [as length])]; 157 range:NSMakeRange(0, [as length])];
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 NSMatrix* matrix = [popup_ contentView]; 253 NSMatrix* matrix = [popup_ contentView];
257 [matrix setTarget:nil]; 254 [matrix setTarget:nil];
258 255
259 popup_.reset(nil); 256 popup_.reset(nil);
260 257
261 return; 258 return;
262 } 259 }
263 260
264 CreatePopupIfNeeded(); 261 CreatePopupIfNeeded();
265 262
263 // Load the results into the popup's matrix.
264 AutocompleteMatrix* matrix = [popup_ contentView];
265 const size_t rows = model_->result().size();
266 DCHECK_GT(rows, 0U);
267 [matrix renewRows:rows columns:1];
268 for (size_t ii = 0; ii < rows; ++ii) {
269 AutocompleteButtonCell* cell = [matrix cellAtRow:ii column:0];
270 const AutocompleteMatch& match = model_->result().match_at(ii);
271 [cell setImage:MatchIcon(match)];
272 [cell setAttributedTitle:MatchText(match, [field_ font])];
273 }
274
266 // Layout the popup and size it to land underneath the field. 275 // Layout the popup and size it to land underneath the field.
267 // TODO(shess) Consider refactoring to remove this depenency, 276 // TODO(shess) Consider refactoring to remove this depenency,
268 // because the popup doesn't need any of the field-like aspects of 277 // because the popup doesn't need any of the field-like aspects of
269 // field_. The edit view could expose helper methods for attaching 278 // field_. The edit view could expose helper methods for attaching
270 // the window to the field. 279 // the window to the field.
271 NSRect r = [field_ bounds]; 280 NSRect r = [field_ bounds];
272 r = [field_ convertRectToBase:r]; 281 r = [field_ convertRectToBase:r];
273 r.origin = [[field_ window] convertBaseToScreen:r.origin]; 282 r.origin = [[field_ window] convertBaseToScreen:r.origin];
274 283
275 AutocompleteMatrix* matrix = [popup_ contentView]; 284 // Set the cell size to fit a line of text in the cell's font. All
276 [matrix setCellSize:NSMakeSize(r.size.width, [matrix cellSize].height)]; 285 // cells should use the same font and layout to one line.
286 NSRect bigRect = [matrix bounds];
287 // TODO(shess): Why 1000.0? Because it's "big enough". Find
288 // something better.
289 bigRect.size.height = 1000.0;
290 NSSize cellSize = [[matrix cellAtRow:0 column:0] cellSizeForBounds:bigRect];
291 [matrix setCellSize:NSMakeSize(r.size.width, cellSize.height)];
292
293 // Make the matrix big enough to hold all the cells.
294 [matrix sizeToCells];
277 [matrix setFrameSize:NSMakeSize(r.size.width, [matrix frame].size.height)]; 295 [matrix setFrameSize:NSMakeSize(r.size.width, [matrix frame].size.height)];
278 296
279 size_t rows = model_->result().size(); 297 // Make the window just as big.
280 [matrix renewRows:rows columns:1];
281 [matrix sizeToCells];
282 r.size.height = [matrix frame].size.height; 298 r.size.height = [matrix frame].size.height;
283 r.origin.y -= r.size.height + 2; 299 r.origin.y -= r.size.height + 2;
284 300
285 for (size_t ii = 0; ii < rows; ++ii) {
286 AutocompleteButtonCell* cell = [matrix cellAtRow:ii column:0];
287 const AutocompleteMatch& match = model_->result().match_at(ii);
288 [cell setImage:MatchIcon(match)];
289 [cell setAttributedTitle:MatchText(match)];
290 }
291
292 // Update the selection. 301 // Update the selection.
293 PaintUpdatesNow(); 302 PaintUpdatesNow();
294 303
295 [popup_ setFrame:r display:YES]; 304 [popup_ setFrame:r display:YES];
296 305
297 if (!IsOpen()) { 306 if (!IsOpen()) {
298 [[field_ window] addChildWindow:popup_ ordered:NSWindowAbove]; 307 [[field_ window] addChildWindow:popup_ ordered:NSWindowAbove];
299 } 308 }
300 } 309 }
301 310
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
432 } 441 }
433 return self; 442 return self;
434 } 443 }
435 444
436 - (void)select:sender { 445 - (void)select:sender {
437 DCHECK(popup_view_); 446 DCHECK(popup_view_);
438 popup_view_->AcceptInput(); 447 popup_view_->AcceptInput();
439 } 448 }
440 449
441 @end 450 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698