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

Unified Diff: chrome/browser/cocoa/autocomplete_text_field_cell.mm

Issue 1566004: [Mac] Rearrange SSL status icon/label in omnibox. (Closed)
Patch Set: Rohit's points. Created 10 years, 9 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/cocoa/autocomplete_text_field_cell.mm
diff --git a/chrome/browser/cocoa/autocomplete_text_field_cell.mm b/chrome/browser/cocoa/autocomplete_text_field_cell.mm
index 5fb7b16388266b2ed17ac740faee880d54e769bb..c8f2122afbcbed9a6028b9dc207bc17eae77e306 100644
--- a/chrome/browser/cocoa/autocomplete_text_field_cell.mm
+++ b/chrome/browser/cocoa/autocomplete_text_field_cell.mm
@@ -39,12 +39,14 @@ const NSInteger kKeywordHintImageBaseline = -6;
const NSInteger kIconHorizontalPad = 3;
// How far to shift bounding box of hint icon label down from top of field.
-const NSInteger kIconLabelYOffset = 5;
+const NSInteger kIconLabelYOffset = 7;
// How far the editor insets itself, for purposes of determining if
// decorations need to be trimmed.
const CGFloat kEditorHorizontalInset = 3.0;
+const CGFloat kLocationIconXOffset = 3.0;
+
// Conveniences to centralize width+offset calculations.
CGFloat WidthForHint(NSAttributedString* hintString) {
return kHintXOffset + ceil([hintString size].width);
@@ -54,6 +56,16 @@ CGFloat WidthForKeyword(NSAttributedString* keywordString) {
2 * kKeywordTokenInset;
}
+// Convenience to draw |image| in the |rect| portion of |view|.
+void DrawImageInRect(NSImage* image, NSView* view, const NSRect& rect) {
+ DCHECK(NSEqualSizes([image size], rect.size));
+ [image setFlipped:[view isFlipped]];
+ [image drawInRect:rect
+ fromRect:NSZeroRect // Entire image
+ operation:NSCompositeSourceOver
+ fraction:1.0];
+}
+
} // namespace
@implementation AutocompleteTextFieldIcon
@@ -61,13 +73,52 @@ CGFloat WidthForKeyword(NSAttributedString* keywordString) {
@synthesize rect = rect_;
@synthesize view = view_;
-+ (AutocompleteTextFieldIcon*)
- iconWithRect:(NSRect)rect
- view:(LocationBarViewMac::LocationBarImageView*)view {
- AutocompleteTextFieldIcon* result = [[AutocompleteTextFieldIcon alloc] init];
- [result setRect:rect];
- [result setView:view];
- return [result autorelease];
+// Private helper.
+- (id)initWithView:(LocationBarViewMac::LocationBarImageView*)view
+ isLabel:(BOOL)isLabel {
+ self = [super init];
+ if (self) {
+ isLabel_ = isLabel;
+ view_ = view;
+ rect_ = NSZeroRect;
+ }
+ return self;
+}
+
+- (id)initImageWithView:(LocationBarViewMac::LocationBarImageView*)view {
+ return [self initWithView:view isLabel:NO];
+}
+
+- (id)initLabelWithView:(LocationBarViewMac::LocationBarImageView*)view {
+ return [self initWithView:view isLabel:YES];
+}
+
+- (void)positionInFrame:(NSRect)frame {
+ if (isLabel_) {
+ NSAttributedString* label = view_->GetLabel();
+ DCHECK(label);
+ const CGFloat labelWidth = ceil([label size].width);
+ rect_ = NSMakeRect(NSMaxX(frame) - labelWidth,
+ NSMinY(frame) + kIconLabelYOffset,
+ labelWidth, NSHeight(frame) - kIconLabelYOffset);
+ } else {
+ const NSSize imageSize = view_->GetImageSize();
+ const CGFloat yOffset = floor((NSHeight(frame) - imageSize.height) / 2);
+ rect_ = NSMakeRect(NSMaxX(frame) - imageSize.width,
+ NSMinY(frame) + yOffset,
+ imageSize.width, imageSize.height);
+ }
+}
+
+- (void)drawInView:(NSView*)controlView {
+ // Make sure someone called |-positionInFrame:|.
+ DCHECK(!NSIsEmptyRect(rect_));
+ if (isLabel_) {
+ NSAttributedString* label = view_->GetLabel();
+ [label drawInRect:rect_];
+ } else {
+ DrawImageInRect(view_->GetImage(), controlView, rect_);
+ }
}
@end
@@ -214,7 +265,11 @@ CGFloat WidthForKeyword(NSAttributedString* keywordString) {
}
- (void)setLocationIconView:(LocationBarViewMac::LocationIconView*)view {
- location_icon_view_ = view;
+ locationIconView_ = view;
+}
+
+- (void)setSecurityLabelView:(LocationBarViewMac::LocationBarImageView*)view {
+ securityLabelView_ = view;
}
- (void)setContentSettingViewsList:
@@ -226,69 +281,57 @@ CGFloat WidthForKeyword(NSAttributedString* keywordString) {
- (NSRect)textFrameForFrame:(NSRect)cellFrame {
NSRect textFrame([super textFrameForFrame:cellFrame]);
+ // TODO(shess): Check the set of exclusions in |LocationBarViewMac|.
+ // If |keywordString_| takes precedence over other cases, then this
+ // code could be made simpler.
+ if (!keywordString_ && locationIconView_ && locationIconView_->IsVisible()) {
+ const NSSize imageSize = locationIconView_->GetImageSize();
+ textFrame.origin.x += imageSize.width;
+ textFrame.size.width -= imageSize.width;
+ }
+
if (hintString_) {
DCHECK(!keywordString_);
const CGFloat hintWidth(WidthForHint(hintString_));
// TODO(shess): This could be better. Show the hint until the
// non-hint text bumps against it?
- if (hintWidth < NSWidth(cellFrame)) {
+ if (hintWidth < NSWidth(textFrame)) {
textFrame.size.width -= hintWidth;
}
} else if (keywordString_) {
DCHECK(!hintString_);
const CGFloat keywordWidth(WidthForKeyword(keywordString_));
- // TODO(shess): This could be better. There's support for a
- // "short" version of the keyword string, work that in in a
- // follow-on pass.
- if (keywordWidth < NSWidth(cellFrame)) {
+ if (keywordWidth < NSWidth(textFrame)) {
textFrame.origin.x += keywordWidth;
- textFrame.size.width = NSMaxX(cellFrame) - NSMinX(textFrame);
+ textFrame.size.width -= keywordWidth;
}
} else {
- // Leave room for images on the right (lock icon etc).
+ // Leave room for items on the right (SSL label, page actions,
+ // etc). Icons are laid out in |cellFrame| rather than
+ // |textFrame| for consistency with drawing code.
NSArray* iconFrames = [self layedOutIcons:cellFrame];
- CGFloat width = 0;
- if ([iconFrames count] > 0)
- width = NSMaxX(cellFrame) - NSMinX([[iconFrames lastObject] rect]);
- if (width > 0)
- width += kIconHorizontalPad;
- if (width < NSWidth(cellFrame))
- textFrame.size.width -= width;
+ if ([iconFrames count]) {
+ const CGFloat minX = NSMinX([[iconFrames objectAtIndex:0] rect]);
+ if (minX >= NSMinX(textFrame)) {
+ textFrame.size.width = minX - NSMinX(textFrame);
+ }
+ }
}
return textFrame;
}
-// Returns a rect of size |imageSize| centered vertically and right-justified in
-// the |box|, with its top left corner |margin| pixels from the right end of the
-// box. (The image thus occupies part of the |margin|.)
-- (NSRect)rightJustifyImage:(NSSize)imageSize
- inRect:(NSRect)box
- withMargin:(CGFloat)margin {
- box.origin.x += box.size.width - margin;
- box.origin.y += floor((box.size.height - imageSize.height) / 2);
- box.size = imageSize;
- return box;
-}
-
- (NSRect)locationIconFrameForFrame:(NSRect)cellFrame {
- if (!location_icon_view_ || !location_icon_view_->IsVisible()) {
+ if (!locationIconView_ || !locationIconView_->IsVisible())
return NSZeroRect;
- }
-
- // Calculate the total width occupied by the image, label, and padding.
- NSSize imageSize = [location_icon_view_->GetImage() size];
- CGFloat widthUsed = imageSize.width + kIconHorizontalPad;
- NSAttributedString* label = location_icon_view_->GetLabel();
- if (label) {
- widthUsed += ceil([label size].width) + kHintXOffset;
- }
- return [self rightJustifyImage:imageSize
- inRect:cellFrame
- withMargin:widthUsed];
+ const NSSize imageSize = locationIconView_->GetImageSize();
+ const CGFloat yOffset = floor((NSHeight(cellFrame) - imageSize.height) / 2);
+ return NSMakeRect(NSMinX(cellFrame) + kLocationIconXOffset,
+ NSMinY(cellFrame) + yOffset,
+ imageSize.width, imageSize.height);
}
- (size_t)pageActionCount {
@@ -359,42 +402,19 @@ CGFloat WidthForKeyword(NSAttributedString* keywordString) {
[keywordString_.get() drawInRect:infoFrame];
}
-- (void)drawImageView:(LocationBarViewMac::LocationBarImageView*)imageView
- inFrame:(NSRect)imageFrame
- inView:(NSView*)controlView {
- // If there's a label, draw it to the right of the icon. The caller must have
- // left sufficient space.
- NSAttributedString* label = imageView->GetLabel();
- if (label) {
- CGFloat labelWidth = ceil([label size].width) + kHintXOffset;
- NSRect textFrame(NSMakeRect(NSMaxX(imageFrame) + kIconHorizontalPad,
- imageFrame.origin.y + kIconLabelYOffset,
- labelWidth,
- imageFrame.size.height - kIconLabelYOffset));
- [label drawInRect:textFrame];
+- (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView*)controlView {
+ if (!keywordString_ && locationIconView_ && locationIconView_->IsVisible()) {
+ DrawImageInRect(locationIconView_->GetImage(), controlView,
+ [self locationIconFrameForFrame:cellFrame]);
}
- // Draw the entire image.
- NSRect imageRect = NSZeroRect;
- NSImage* image = imageView->GetImage();
- image.size = [image size];
- [image setFlipped:[controlView isFlipped]];
- [image drawInRect:imageFrame
- fromRect:imageRect
- operation:NSCompositeSourceOver
- fraction:1.0];
-}
-
-- (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView*)controlView {
if (hintString_) {
[self drawHintWithFrame:cellFrame inView:controlView];
} else if (keywordString_) {
[self drawKeywordWithFrame:cellFrame inView:controlView];
} else {
for (AutocompleteTextFieldIcon* icon in [self layedOutIcons:cellFrame]) {
- [self drawImageView:[icon view]
- inFrame:[icon rect]
- inView:controlView];
+ [icon drawInView:controlView];
}
}
@@ -402,71 +422,108 @@ CGFloat WidthForKeyword(NSAttributedString* keywordString) {
}
- (NSArray*)layedOutIcons:(NSRect)cellFrame {
- NSMutableArray* result = [NSMutableArray arrayWithCapacity:0];
- NSRect iconFrame = cellFrame;
- if (location_icon_view_ && location_icon_view_->IsVisible()) {
- NSRect locationIconFrame = [self locationIconFrameForFrame:iconFrame];
- [result addObject:
- [AutocompleteTextFieldIcon iconWithRect:locationIconFrame
- view:location_icon_view_]];
- iconFrame.size.width -= NSMaxX(iconFrame) - NSMinX(locationIconFrame);
+ // The set of views to display right-justified in the cell, from
+ // left to right.
+ NSMutableArray* result = [NSMutableArray array];
+
+ // Security label floats to left of page actions.
+ if (securityLabelView_ && securityLabelView_->IsVisible() &&
+ securityLabelView_->GetLabel()) {
+ scoped_nsobject<AutocompleteTextFieldIcon> icon(
+ [[AutocompleteTextFieldIcon alloc]
+ initLabelWithView:securityLabelView_]);
+ [result addObject:icon];
}
- const size_t pageActionCount = [self pageActionCount];
- for (size_t i = 0; i < pageActionCount; ++i) {
- LocationBarViewMac::PageActionImageView* view =
- page_action_views_->ViewAt(i);
- if (view->IsVisible()) {
- // If this function is called right after a page action icon has been
- // created, the images for all views will still be loading; in this case,
- // each visible view will give us its default size.
- NSSize iconSize = view->GetPreferredImageSize();
- NSRect pageActionFrame =
- [self rightJustifyImage:iconSize
- inRect:iconFrame
- withMargin:kIconHorizontalPad + iconSize.width];
- [result addObject:
- [AutocompleteTextFieldIcon iconWithRect:pageActionFrame view:view]];
- iconFrame.size.width -= NSMaxX(iconFrame) - NSMinX(pageActionFrame);
- }
- }
+ // Collect the image views for bulk processing.
+ // TODO(shess): Refactor with LocationBarViewMac to make the
+ // different types of items more consistent.
+ std::vector<LocationBarViewMac::LocationBarImageView*> views;
if (content_setting_views_) {
- // We use a reverse_iterator here because we're laying out the views from
- // right to left but in the vector they're ordered left to right.
- for (LocationBarViewMac::ContentSettingViews::const_reverse_iterator
- it(content_setting_views_->rbegin());
- it != const_cast<const LocationBarViewMac::ContentSettingViews*>(
- content_setting_views_)->rend();
- ++it) {
- if ((*it)->IsVisible()) {
- NSImage* image = (*it)->GetImage();
- NSRect blockedContentFrame =
- [self rightJustifyImage:[image size]
- inRect:iconFrame
- withMargin:[image size].width + kIconHorizontalPad];
- [result addObject:
- [AutocompleteTextFieldIcon iconWithRect:blockedContentFrame
- view:*it]];
- iconFrame.size.width -= NSMaxX(iconFrame) - NSMinX(blockedContentFrame);
- }
+ views.insert(views.end(),
+ content_setting_views_->begin(),
+ content_setting_views_->end());
+ }
+
+ // TODO(shess): Previous implementation of this method made a
+ // right-to-left array, so add the page-action items in that order.
+ // As part of the refactor mentioned above, lay everything out
+ // nicely left-to-right.
+ for (size_t i = [self pageActionCount]; i-- > 0;) {
+ views.push_back(page_action_views_->ViewAt(i));
+ }
+
+ // Load the visible views into |result|.
+ for (std::vector<LocationBarViewMac::LocationBarImageView*>::const_iterator
+ iter = views.begin(); iter != views.end(); ++iter) {
+ if ((*iter)->IsVisible()) {
+ scoped_nsobject<AutocompleteTextFieldIcon> icon(
+ [[AutocompleteTextFieldIcon alloc] initImageWithView:*iter]);
+ [result addObject:icon];
}
}
+
+ // Leave a boundary at RHS of field.
+ cellFrame.size.width -= kHintXOffset;
+
+ // Position each view within the frame from right to left.
+ for (AutocompleteTextFieldIcon* icon in [result reverseObjectEnumerator]) {
+ [icon positionInFrame:cellFrame];
+
+ // Trim the icon's space from the frame.
+ cellFrame.size.width = NSMinX([icon rect]) - kIconHorizontalPad;
+ }
return result;
}
-- (NSMenu*)actionMenuForEvent:(NSEvent*)event
- inRect:(NSRect)cellFrame
- ofView:(NSView*)aView {
- NSPoint location = [aView convertPoint:[event locationInWindow] fromView:nil];
+- (AutocompleteTextFieldIcon*)iconForEvent:(NSEvent*)theEvent
+ inRect:(NSRect)cellFrame
+ ofView:(AutocompleteTextField*)controlView {
+ const BOOL flipped = [controlView isFlipped];
+ const NSPoint location =
+ [controlView convertPoint:[theEvent locationInWindow] fromView:nil];
+
+ // Special check for location image, it is not in |-layedOutIcons:|.
+ const NSRect locationIconFrame = [self locationIconFrameForFrame:cellFrame];
+ if (NSMouseInRect(location, locationIconFrame, flipped)) {
+ // Make up an icon to return.
+ AutocompleteTextFieldIcon* icon =
+ [[[AutocompleteTextFieldIcon alloc]
+ initImageWithView:locationIconView_] autorelease];
+ [icon setRect:locationIconFrame];
+ return icon;
+ }
- const BOOL flipped = [aView isFlipped];
for (AutocompleteTextFieldIcon* icon in [self layedOutIcons:cellFrame]) {
- if (NSMouseInRect(location, [icon rect], flipped)) {
- return [icon view]->GetMenu();
- }
+ if (NSMouseInRect(location, [icon rect], flipped))
+ return icon;
}
+
+ return nil;
+}
+
+- (NSMenu*)actionMenuForEvent:(NSEvent*)theEvent
+ inRect:(NSRect)cellFrame
+ ofView:(AutocompleteTextField*)controlView {
+ AutocompleteTextFieldIcon*
+ icon = [self iconForEvent:theEvent inRect:cellFrame ofView:controlView];
+ if (icon)
+ return [icon view]->GetMenu();
return nil;
}
+- (BOOL)mouseDown:(NSEvent*)theEvent
+ inRect:(NSRect)cellFrame
+ ofView:(AutocompleteTextField*)controlView {
+ AutocompleteTextFieldIcon*
+ icon = [self iconForEvent:theEvent inRect:cellFrame ofView:controlView];
+ if (icon) {
+ [icon view]->OnMousePressed([icon rect]);
+ return YES;
+ }
+
+ return NO;
+}
+
@end
« no previous file with comments | « chrome/browser/cocoa/autocomplete_text_field_cell.h ('k') | chrome/browser/cocoa/autocomplete_text_field_cell_unittest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698