Index: chrome/browser/ui/cocoa/omnibox/omnibox_popup_cell.mm |
diff --git a/chrome/browser/ui/cocoa/omnibox/omnibox_popup_cell.mm b/chrome/browser/ui/cocoa/omnibox/omnibox_popup_cell.mm |
index 5b042bb8d4fe5eb6a01fecc9f44725c26225a46e..8824ccee8c9ad7e1484313a328d853ecac669e4c 100644 |
--- a/chrome/browser/ui/cocoa/omnibox/omnibox_popup_cell.mm |
+++ b/chrome/browser/ui/cocoa/omnibox/omnibox_popup_cell.mm |
@@ -18,11 +18,14 @@ |
#include "base/strings/utf_string_conversions.h" |
#include "chrome/browser/ui/cocoa/omnibox/omnibox_popup_view_mac.h" |
#include "chrome/browser/ui/cocoa/omnibox/omnibox_view_mac.h" |
+#import "chrome/browser/ui/cocoa/themed_window.h" |
#include "chrome/grit/generated_resources.h" |
#include "components/omnibox/browser/omnibox_popup_model.h" |
#include "components/omnibox/browser/suggestion_answer.h" |
#include "skia/ext/skia_utils_mac.h" |
#include "ui/base/l10n/l10n_util.h" |
+#include "ui/base/material_design/material_design_controller.h" |
+#include "ui/gfx/color_palette.h" |
#include "ui/gfx/font.h" |
namespace { |
@@ -30,15 +33,34 @@ namespace { |
// How far to offset image column from the left. |
const CGFloat kImageXOffset = 5.0; |
-// How far to offset image and text. |
-const CGFloat kPaddingOffset = 3.0; |
+// How far to offset text. |
+const CGFloat kVerticalTextPadding = 3.0; |
+ |
+const CGFloat kVerticalImagePadding = 3.0; |
+const CGFloat kMaterialVerticalImagePadding = 5.0; |
-// How far to offset the text column from the left. |
const CGFloat kTextStartOffset = 28.0; |
+const CGFloat kMaterialTextStartOffset = 25.0; |
// Rounding radius of selection and hover background on popup items. |
const CGFloat kCellRoundingRadius = 2.0; |
+// How far to offset the image. |
+CGFloat VerticalImagePadding() { |
+ if (!ui::MaterialDesignController::IsModeMaterial()) { |
+ return kVerticalImagePadding; |
+ } |
+ return kMaterialVerticalImagePadding; |
+} |
+ |
+// How far to offset the text column from the left. |
+CGFloat TextStartOffset() { |
+ if (!ui::MaterialDesignController::IsModeMaterial()) { |
+ return kTextStartOffset; |
+ } |
+ return kMaterialTextStartOffset; |
+} |
+ |
// Flips the given |rect| in context of the given |frame|. |
NSRect FlipIfRTL(NSRect rect, NSRect frame) { |
DCHECK_LE(NSMinX(frame), NSMinX(rect)); |
@@ -51,18 +73,35 @@ NSRect FlipIfRTL(NSRect rect, NSRect frame) { |
return rect; |
} |
-NSColor* SelectedBackgroundColor() { |
+NSColor* SelectedBackgroundColor(BOOL is_dark_theme) { |
+ if (is_dark_theme && ui::MaterialDesignController::IsModeMaterial()) { |
+ return skia::SkColorToSRGBNSColor(SkColorSetA(SK_ColorWHITE, 0x14)); |
+ } |
return [NSColor selectedControlColor]; |
} |
-NSColor* HoveredBackgroundColor() { |
+ |
+NSColor* HoveredBackgroundColor(BOOL is_dark_theme) { |
+ if (is_dark_theme) { |
+ return skia::SkColorToSRGBNSColor(SkColorSetA(SK_ColorWHITE, 0x0D)); |
+ } |
return [NSColor controlHighlightColor]; |
} |
-NSColor* ContentTextColor() { |
+NSColor* ContentTextColor(BOOL is_dark_theme) { |
+ if (ui::MaterialDesignController::IsModeMaterial() && is_dark_theme) { |
+ return [NSColor whiteColor]; |
+ } |
return [NSColor blackColor]; |
} |
-NSColor* DimTextColor() { |
- return [NSColor darkGrayColor]; |
+NSColor* DimTextColor(BOOL is_dark_theme) { |
+ if (!ui::MaterialDesignController::IsModeMaterial()) { |
+ return [NSColor darkGrayColor]; |
+ } |
+ if (is_dark_theme) { |
+ return skia::SkColorToSRGBNSColor(SkColorSetA(SK_ColorWHITE, 0x7F)); |
+ } |
+ const SkColor kDimTextColor = 0xFF646464; |
tapted
2016/04/28 14:29:44
nit: SkColorSetRGB, to be consistent with the stuf
shrike
2016/04/28 21:05:35
Done.
|
+ return skia::SkColorToSRGBNSColor(kDimTextColor); |
} |
NSColor* PositiveTextColor() { |
return skia::SkColorToCalibratedNSColor(SkColorSetRGB(0x3d, 0x94, 0x00)); |
@@ -70,7 +109,10 @@ NSColor* PositiveTextColor() { |
NSColor* NegativeTextColor() { |
return skia::SkColorToCalibratedNSColor(SkColorSetRGB(0xdd, 0x4b, 0x39)); |
} |
-NSColor* URLTextColor() { |
+NSColor* URLTextColor(BOOL is_dark_theme) { |
+ if (ui::MaterialDesignController::IsModeMaterial() && is_dark_theme) { |
+ return skia::SkColorToSRGBNSColor(gfx::kGoogleBlue300); |
+ } |
return [NSColor colorWithCalibratedRed:0.0 green:0.55 blue:0.0 alpha:1.0]; |
} |
@@ -91,22 +133,20 @@ NSFont* LargeSuperscriptFont() { |
NSFontDescriptor* descriptor = [font fontDescriptor]; |
return [NSFont fontWithDescriptor:descriptor size:size]; |
} |
-NSFont* SmallFont() { |
- return OmniboxViewMac::GetSmallFont(gfx::Font::NORMAL); |
-} |
CGFloat GetContentAreaWidth(NSRect cellFrame) { |
- return NSWidth(cellFrame) - kTextStartOffset; |
+ return NSWidth(cellFrame) - TextStartOffset(); |
} |
NSAttributedString* CreateAnswerStringHelper(const base::string16& text, |
NSInteger style_type, |
- bool is_bold) { |
+ bool is_bold, |
+ BOOL is_dark_theme) { |
NSDictionary* answer_style = nil; |
switch (style_type) { |
case SuggestionAnswer::TOP_ALIGNED: |
answer_style = @{ |
- NSForegroundColorAttributeName : DimTextColor(), |
+ NSForegroundColorAttributeName : DimTextColor(is_dark_theme), |
NSFontAttributeName : LargeSuperscriptFont(), |
NSSuperscriptAttributeName : @1 |
}; |
@@ -125,38 +165,38 @@ NSAttributedString* CreateAnswerStringHelper(const base::string16& text, |
break; |
case SuggestionAnswer::PERSONALIZED_SUGGESTION: |
answer_style = @{ |
- NSForegroundColorAttributeName : ContentTextColor(), |
+ NSForegroundColorAttributeName : ContentTextColor(is_dark_theme), |
NSFontAttributeName : FieldFont() |
}; |
break; |
case SuggestionAnswer::ANSWER_TEXT_MEDIUM: |
answer_style = @{ |
- NSForegroundColorAttributeName : ContentTextColor(), |
+ NSForegroundColorAttributeName : ContentTextColor(is_dark_theme), |
NSFontAttributeName : FieldFont() |
}; |
break; |
case SuggestionAnswer::ANSWER_TEXT_LARGE: |
answer_style = @{ |
- NSForegroundColorAttributeName : ContentTextColor(), |
+ NSForegroundColorAttributeName : ContentTextColor(is_dark_theme), |
NSFontAttributeName : LargeFont() |
}; |
break; |
case SuggestionAnswer::SUGGESTION_SECONDARY_TEXT_SMALL: |
answer_style = @{ |
- NSForegroundColorAttributeName : DimTextColor(), |
- NSFontAttributeName : SmallFont() |
+ NSForegroundColorAttributeName : DimTextColor(is_dark_theme), |
+ NSFontAttributeName : FieldFont() |
tapted
2016/04/28 14:29:44
Will this change font sizes for non-material as we
shrike
2016/04/28 21:05:35
Thank you for catching that.
|
}; |
break; |
case SuggestionAnswer::SUGGESTION_SECONDARY_TEXT_MEDIUM: |
answer_style = @{ |
- NSForegroundColorAttributeName : DimTextColor(), |
- NSFontAttributeName : FieldFont() |
+ NSForegroundColorAttributeName : DimTextColor(is_dark_theme), |
+ NSFontAttributeName : LargeSuperscriptFont() |
}; |
break; |
case SuggestionAnswer::SUGGESTION: // Fall through. |
default: |
answer_style = @{ |
- NSForegroundColorAttributeName : ContentTextColor (), |
+ NSForegroundColorAttributeName : ContentTextColor(is_dark_theme), |
NSFontAttributeName : FieldFont() |
}; |
break; |
@@ -176,7 +216,8 @@ NSAttributedString* CreateAnswerStringHelper(const base::string16& text, |
} |
NSAttributedString* CreateAnswerString(const base::string16& text, |
- NSInteger style_type) { |
+ NSInteger style_type, |
+ BOOL is_dark_theme) { |
// TODO(dschuyler): make this better. Right now this only supports unnested |
// bold tags. In the future we'll need to flag unexpected tags while adding |
// support for b, i, u, sub, and sup. We'll also need to support HTML |
@@ -192,45 +233,55 @@ NSAttributedString* CreateAnswerString(const base::string16& text, |
[result |
appendAttributedString:CreateAnswerStringHelper( |
text.substr(begin), |
- style_type, false)]; |
+ style_type, |
+ false, |
+ is_dark_theme)]; |
break; |
} |
[result appendAttributedString:CreateAnswerStringHelper( |
text.substr(begin, end - begin), |
- style_type, false)]; |
+ style_type, |
+ false, |
+ is_dark_theme)]; |
begin = end + begin_tag.length(); |
end = text.find(end_tag, begin); |
if (end == base::string16::npos) |
break; |
[result appendAttributedString:CreateAnswerStringHelper( |
text.substr(begin, end - begin), |
- style_type, true)]; |
+ style_type, |
+ true, |
+ is_dark_theme)]; |
begin = end + end_tag.length(); |
} |
return result.autorelease(); |
} |
-NSAttributedString* CreateAnswerLine(const SuggestionAnswer::ImageLine& line) { |
+NSAttributedString* CreateAnswerLine(const SuggestionAnswer::ImageLine& line, |
+ BOOL is_dark_theme) { |
base::scoped_nsobject<NSMutableAttributedString> answer_string( |
[[NSMutableAttributedString alloc] init]); |
DCHECK(!line.text_fields().empty()); |
for (const SuggestionAnswer::TextField& text_field : line.text_fields()) { |
[answer_string |
appendAttributedString:CreateAnswerString(text_field.text(), |
- text_field.type())]; |
+ text_field.type(), |
+ is_dark_theme)]; |
} |
const base::string16 space(base::ASCIIToUTF16(" ")); |
const SuggestionAnswer::TextField* text_field = line.additional_text(); |
if (text_field) { |
[answer_string |
appendAttributedString:CreateAnswerString(space + text_field->text(), |
- text_field->type())]; |
+ text_field->type(), |
+ is_dark_theme)]; |
} |
text_field = line.status_text(); |
if (text_field) { |
[answer_string |
appendAttributedString:CreateAnswerString(space + text_field->text(), |
- text_field->type())]; |
+ text_field->type(), |
+ is_dark_theme)]; |
} |
base::scoped_nsobject<NSMutableParagraphStyle> style( |
[[NSMutableParagraphStyle alloc] init]); |
@@ -277,7 +328,8 @@ NSMutableAttributedString* CreateAttributedString( |
NSAttributedString* CreateClassifiedAttributedString( |
const base::string16& text, |
NSColor* text_color, |
- const ACMatchClassifications& classifications) { |
+ const ACMatchClassifications& classifications, |
+ BOOL is_dark_theme) { |
NSMutableAttributedString* attributedString = |
CreateAttributedString(text, text_color); |
NSUInteger match_length = [attributedString length]; |
@@ -304,11 +356,11 @@ NSAttributedString* CreateClassifiedAttributedString( |
if (0 != (i->style & ACMatchClassification::URL)) { |
[attributedString addAttribute:NSForegroundColorAttributeName |
- value:URLTextColor() |
+ value:URLTextColor(is_dark_theme) |
range:range]; |
} else if (0 != (i->style & ACMatchClassification::DIM)) { |
[attributedString addAttribute:NSForegroundColorAttributeName |
- value:DimTextColor() |
+ value:DimTextColor(is_dark_theme) |
range:range]; |
} |
} |
@@ -322,10 +374,12 @@ NSAttributedString* CreateClassifiedAttributedString( |
- (CGFloat)drawMatchPart:(NSAttributedString*)attributedString |
withFrame:(NSRect)cellFrame |
origin:(NSPoint)origin |
- withMaxWidth:(int)maxWidth; |
+ withMaxWidth:(int)maxWidth |
+ forDarkTheme:(BOOL)isDarkTheme; |
- (CGFloat)drawMatchPrefixWithFrame:(NSRect)cellFrame |
tableView:(OmniboxPopupMatrix*)tableView |
- withContentsMaxWidth:(int*)contentsMaxWidth; |
+ withContentsMaxWidth:(int*)contentsMaxWidth |
+ forDarkTheme:(BOOL)isDarkTheme; |
- (void)drawMatchWithFrame:(NSRect)cellFrame inView:(NSView*)controlView; |
@end |
@@ -335,6 +389,7 @@ NSAttributedString* CreateClassifiedAttributedString( |
@synthesize description = description_; |
@synthesize prefix = prefix_; |
@synthesize image = image_; |
+@synthesize incognitoImage = incognitoImage_; |
@synthesize answerImage = answerImage_; |
@synthesize contentsOffset = contentsOffset_; |
@synthesize isContentsRTL = isContentsRTL_; |
@@ -344,7 +399,8 @@ NSAttributedString* CreateClassifiedAttributedString( |
- (instancetype)initWithMatch:(const AutocompleteMatch&)match |
contentsOffset:(CGFloat)contentsOffset |
image:(NSImage*)image |
- answerImage:(NSImage*)answerImage { |
+ answerImage:(NSImage*)answerImage |
+ forDarkTheme:(BOOL)isDarkTheme { |
if ((self = [super init])) { |
image_ = [image retain]; |
answerImage_ = [answerImage retain]; |
@@ -363,24 +419,38 @@ NSAttributedString* CreateClassifiedAttributedString( |
prefix_ = |
[CreateAttributedString(base::UTF8ToUTF16(match.GetAdditionalInfo( |
kACMatchPropertyContentsPrefix)), |
- ContentTextColor(), textAlignment) retain]; |
+ ContentTextColor(isDarkTheme), |
+ textAlignment) retain]; |
isAnswer_ = !!match.answer; |
if (isAnswer_) { |
- contents_ = [CreateAnswerLine(match.answer->first_line()) retain]; |
- description_ = [CreateAnswerLine(match.answer->second_line()) retain]; |
+ contents_ = |
+ [CreateAnswerLine(match.answer->first_line(), isDarkTheme) retain]; |
+ description_ = |
+ [CreateAnswerLine(match.answer->second_line(), isDarkTheme) retain]; |
} else { |
- contents_ = [CreateClassifiedAttributedString( |
- match.contents, ContentTextColor(), match.contents_class) retain]; |
+ contents_ = |
+ [CreateClassifiedAttributedString(match.contents, |
+ ContentTextColor(isDarkTheme), |
+ match.contents_class, |
+ isDarkTheme) retain]; |
if (!match.description.empty()) { |
- description_ = [CreateClassifiedAttributedString( |
- match.description, DimTextColor(), match.description_class) retain]; |
+ description_ = |
+ [CreateClassifiedAttributedString(match.description, |
+ DimTextColor(isDarkTheme), |
+ match.description_class, |
+ isDarkTheme) retain]; |
} |
} |
} |
return self; |
} |
+- (void)dealloc { |
+ [incognitoImage_ release]; |
tapted
2016/04/28 14:29:44
huhhh Where are the other retained properties rele
shrike
2016/04/28 21:05:35
Right - I filed https://crbug.com/596715 for this
|
+ [super dealloc]; |
+} |
+ |
- (instancetype)copyWithZone:(NSZone*)zone { |
return [self retain]; |
} |
@@ -394,16 +464,25 @@ NSAttributedString* CreateClassifiedAttributedString( |
@implementation OmniboxPopupCell |
- (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView*)controlView { |
+ OmniboxPopupMatrix* matrix = |
+ base::mac::ObjCCast<OmniboxPopupMatrix>(controlView); |
tapted
2016/04/28 14:29:44
ObjCCastStrict
shrike
2016/04/28 21:05:35
Done.
|
+ BOOL isDarkTheme = [matrix hasDarkTheme]; |
+ |
if ([self state] == NSOnState || [self isHighlighted]) { |
- if ([self state] == NSOnState) |
- [SelectedBackgroundColor() set]; |
- else |
- [HoveredBackgroundColor() set]; |
- NSBezierPath* path = |
- [NSBezierPath bezierPathWithRoundedRect:cellFrame |
- xRadius:kCellRoundingRadius |
- yRadius:kCellRoundingRadius]; |
- [path fill]; |
+ if ([self state] == NSOnState) { |
+ [SelectedBackgroundColor(isDarkTheme) set]; |
+ } else { |
+ [HoveredBackgroundColor(isDarkTheme) set]; |
+ } |
+ if (ui::MaterialDesignController::IsModeMaterial()) { |
+ NSRectFillUsingOperation(cellFrame, NSCompositeSourceOver); |
+ } else { |
+ NSBezierPath* path = |
+ [NSBezierPath bezierPathWithRoundedRect:cellFrame |
+ xRadius:kCellRoundingRadius |
+ yRadius:kCellRoundingRadius]; |
+ [path fill]; |
+ } |
} |
[self drawMatchWithFrame:cellFrame inView:controlView]; |
@@ -428,34 +507,41 @@ NSAttributedString* CreateClassifiedAttributedString( |
&contentsMaxWidth, |
&descriptionMaxWidth); |
+ NSWindow* parentWindow = [[controlView window] parentWindow]; |
+ BOOL isDarkTheme = [parentWindow hasDarkTheme]; |
NSRect imageRect = cellFrame; |
- imageRect.size = [[cellData image] size]; |
- imageRect.origin.x += kImageXOffset; |
- imageRect.origin.y += kPaddingOffset; |
- [[cellData image] drawInRect:FlipIfRTL(imageRect, cellFrame) |
- fromRect:NSZeroRect |
- operation:NSCompositeSourceOver |
- fraction:1.0 |
- respectFlipped:YES |
- hints:nil]; |
- |
- NSPoint origin = NSMakePoint(kTextStartOffset, kPaddingOffset); |
+ NSImage* theImage = |
+ isDarkTheme ? [cellData incognitoImage] : [cellData image]; |
+ imageRect.size = [theImage size]; |
+ imageRect.origin.x += kImageXOffset + [tableView contentLeftPadding]; |
+ imageRect.origin.y += VerticalImagePadding(); |
+ [theImage drawInRect:FlipIfRTL(imageRect, cellFrame) |
+ fromRect:NSZeroRect |
+ operation:NSCompositeSourceOver |
+ fraction:1.0 |
+ respectFlipped:YES |
+ hints:nil]; |
+ |
+ NSPoint origin = NSMakePoint( |
+ TextStartOffset() + [tableView contentLeftPadding], kVerticalTextPadding); |
if ([cellData matchType] == AutocompleteMatchType::SEARCH_SUGGEST_TAIL) { |
// Infinite suggestions are rendered with a prefix (usually ellipsis), which |
// appear vertically stacked. |
origin.x += [self drawMatchPrefixWithFrame:cellFrame |
tableView:tableView |
- withContentsMaxWidth:&contentsMaxWidth]; |
+ withContentsMaxWidth:&contentsMaxWidth |
+ forDarkTheme:isDarkTheme]; |
} |
origin.x += [self drawMatchPart:[cellData contents] |
withFrame:cellFrame |
origin:origin |
- withMaxWidth:contentsMaxWidth]; |
+ withMaxWidth:contentsMaxWidth |
+ forDarkTheme:isDarkTheme]; |
if (descriptionMaxWidth > 0) { |
if ([cellData isAnswer]) { |
- origin = |
- NSMakePoint(kTextStartOffset, kContentLineHeight - kPaddingOffset); |
+ origin = NSMakePoint(TextStartOffset(), |
+ kContentLineHeight - kVerticalTextPadding); |
CGFloat imageSize = [tableView answerLineHeight]; |
NSRect imageRect = |
NSMakeRect(NSMinX(cellFrame) + origin.x, NSMinY(cellFrame) + origin.y, |
@@ -467,23 +553,29 @@ NSAttributedString* CreateClassifiedAttributedString( |
respectFlipped:YES |
hints:nil]; |
if ([cellData answerImage]) |
- origin.x += imageSize + kPaddingOffset; |
+ origin.x += imageSize + VerticalImagePadding(); |
} else { |
origin.x += [self drawMatchPart:[tableView separator] |
withFrame:cellFrame |
origin:origin |
- withMaxWidth:separatorWidth]; |
+ withMaxWidth:separatorWidth |
+ forDarkTheme:isDarkTheme]; |
+ } |
+ if (ui::MaterialDesignController::IsModeMaterial()) { |
tapted
2016/04/28 14:29:44
this seems subtle - maybe a comment?
shrike
2016/04/28 21:05:35
Done.
|
+ origin.y += 1; |
} |
origin.x += [self drawMatchPart:[cellData description] |
withFrame:cellFrame |
origin:origin |
- withMaxWidth:descriptionMaxWidth]; |
+ withMaxWidth:descriptionMaxWidth |
+ forDarkTheme:isDarkTheme]; |
} |
} |
- (CGFloat)drawMatchPrefixWithFrame:(NSRect)cellFrame |
tableView:(OmniboxPopupMatrix*)tableView |
- withContentsMaxWidth:(int*)contentsMaxWidth { |
+ withContentsMaxWidth:(int*)contentsMaxWidth |
+ forDarkTheme:(BOOL)isDarkTheme { |
OmniboxPopupCellData* cellData = |
base::mac::ObjCCastStrict<OmniboxPopupCellData>([self objectValue]); |
CGFloat offset = 0.0f; |
@@ -518,15 +610,17 @@ NSAttributedString* CreateClassifiedAttributedString( |
*contentsMaxWidth); |
[self drawMatchPart:[cellData prefix] |
withFrame:cellFrame |
- origin:NSMakePoint(prefixOffset + kTextStartOffset, 0) |
- withMaxWidth:prefixWidth]; |
+ origin:NSMakePoint(prefixOffset + TextStartOffset(), 0) |
+ withMaxWidth:prefixWidth |
+ forDarkTheme:isDarkTheme]; |
return offset; |
} |
- (CGFloat)drawMatchPart:(NSAttributedString*)attributedString |
withFrame:(NSRect)cellFrame |
origin:(NSPoint)origin |
- withMaxWidth:(int)maxWidth { |
+ withMaxWidth:(int)maxWidth |
+ forDarkTheme:(BOOL)isDarkTheme { |
NSRect renderRect = NSIntersectionRect( |
cellFrame, NSOffsetRect(cellFrame, origin.x, origin.y)); |
renderRect.size.width = |
@@ -556,7 +650,7 @@ NSAttributedString* CreateClassifiedAttributedString( |
// Color does not matter. |
NSAttributedString* attributedString = |
- CreateAttributedString(inputText, DimTextColor()); |
+ CreateAttributedString(inputText, DimTextColor(false)); |
base::scoped_nsobject<NSTextStorage> textStorage( |
[[NSTextStorage alloc] initWithAttributedString:attributedString]); |
base::scoped_nsobject<NSLayoutManager> layoutManager( |
@@ -604,10 +698,10 @@ NSAttributedString* CreateClassifiedAttributedString( |
return base::i18n::IsRTL() ? (inputWidth - glyphOffset) : glyphOffset; |
} |
-+ (NSAttributedString*)createSeparatorString { |
++ (NSAttributedString*)createSeparatorStringForDarkTheme:(BOOL)isDarkTheme { |
base::string16 raw_separator = |
l10n_util::GetStringUTF16(IDS_AUTOCOMPLETE_MATCH_DESCRIPTION_SEPARATOR); |
- return CreateAttributedString(raw_separator, DimTextColor()); |
+ return CreateAttributedString(raw_separator, DimTextColor(isDarkTheme)); |
} |
@end |