summaryrefslogtreecommitdiffstats
path: root/chrome/browser/cocoa
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/cocoa')
-rw-r--r--chrome/browser/cocoa/autocomplete_text_field.h7
-rw-r--r--chrome/browser/cocoa/autocomplete_text_field.mm31
-rw-r--r--chrome/browser/cocoa/autocomplete_text_field_cell.h85
-rw-r--r--chrome/browser/cocoa/autocomplete_text_field_cell.mm563
-rw-r--r--chrome/browser/cocoa/autocomplete_text_field_cell_unittest.mm139
-rw-r--r--chrome/browser/cocoa/autocomplete_text_field_editor.mm29
-rw-r--r--chrome/browser/cocoa/autocomplete_text_field_unittest.mm96
-rw-r--r--chrome/browser/cocoa/bookmark_bubble_controller.mm2
-rw-r--r--chrome/browser/cocoa/browser_test_helper.h9
-rw-r--r--chrome/browser/cocoa/browser_window_controller.mm2
-rw-r--r--chrome/browser/cocoa/browser_window_controller_unittest.mm4
-rw-r--r--chrome/browser/cocoa/location_bar_view_mac.h108
-rw-r--r--chrome/browser/cocoa/location_bar_view_mac.mm243
-rw-r--r--chrome/browser/cocoa/location_bar_view_mac_unittest.mm37
-rw-r--r--chrome/browser/cocoa/status_bubble_mac_unittest.mm8
-rw-r--r--chrome/browser/cocoa/tab_strip_controller_unittest.mm2
-rw-r--r--chrome/browser/cocoa/toolbar_controller.h12
-rw-r--r--chrome/browser/cocoa/toolbar_controller.mm104
-rw-r--r--chrome/browser/cocoa/toolbar_controller_unittest.mm34
19 files changed, 938 insertions, 577 deletions
diff --git a/chrome/browser/cocoa/autocomplete_text_field.h b/chrome/browser/cocoa/autocomplete_text_field.h
index 1b1856d..8e16705 100644
--- a/chrome/browser/cocoa/autocomplete_text_field.h
+++ b/chrome/browser/cocoa/autocomplete_text_field.h
@@ -119,6 +119,13 @@ class AutocompleteTextFieldObserver {
// is not over an action.
- (NSMenu*)actionMenuForEvent:(NSEvent*)event;
+// Return the rectangle the star is being shown in, for purposes of
+// positioning the bookmark bubble.
+- (NSRect)starIconFrame;
+
+// If the location icon is draggable, return its drag pasteboard.
+- (NSPasteboard*)locationDragPasteboard;
+
@end
#endif // CHROME_BROWSER_COCOA_AUTOCOMPLETE_TEXT_FIELD_H_
diff --git a/chrome/browser/cocoa/autocomplete_text_field.mm b/chrome/browser/cocoa/autocomplete_text_field.mm
index 60d3507..a07cac1 100644
--- a/chrome/browser/cocoa/autocomplete_text_field.mm
+++ b/chrome/browser/cocoa/autocomplete_text_field.mm
@@ -124,14 +124,10 @@
return;
}
- // If the user clicked on one of the icons (security icon, Page
- // Actions, etc), let the icon handle the click.
- for (AutocompleteTextFieldIcon* icon in [cell layedOutIcons:bounds]) {
- const NSRect iconRect = [icon rect];
- if (NSMouseInRect(location, iconRect, flipped)) {
- [icon view]->OnMousePressed(iconRect);
- return;
- }
+ // Give the cell a chance to intercept clicks in page-actions and
+ // other decorative items.
+ if ([cell mouseDown:theEvent inRect:bounds ofView:self]) {
+ return;
}
NSText* editor = [self currentEditor];
@@ -199,6 +195,7 @@
// Show the I-beam cursor unless the mouse is over an image within the field
// (Page Actions or the security icon) in which case show the arrow cursor.
+// TODO(rohitrao): Should default to the arrow cursor. http://crbug.com/41612
- (void)resetCursorRects {
NSRect fieldBounds = [self bounds];
[self addCursorRect:fieldBounds cursor:[NSCursor IBeamCursor]];
@@ -206,8 +203,17 @@
AutocompleteTextFieldCell* cell = [self autocompleteTextFieldCell];
for (AutocompleteTextFieldIcon* icon in [cell layedOutIcons:fieldBounds])
[self addCursorRect:[icon rect] cursor:[NSCursor arrowCursor]];
+
+ // Special-case the location image, since it is not in |-layedOutIcons|.
+ const NSRect locationIconFrame = [cell locationIconFrameForFrame:fieldBounds];
+ [self addCursorRect:locationIconFrame cursor:[NSCursor arrowCursor]];
}
+// TODO(shess): -resetFieldEditorFrameIfNeeded is the place where
+// changes to the cell layout should be flushed. LocationBarViewMac
+// and ToolbarController are calling this routine directly, and I
+// think they are probably wrong.
+// http://crbug.com/40053
- (void)updateCursorAndToolTipRects {
// This will force |resetCursorRects| to be called, as it is not to be called
// directly.
@@ -371,4 +377,13 @@
actionMenuForEvent:event inRect:[self bounds] ofView:self];
}
+- (NSRect)starIconFrame {
+ AutocompleteTextFieldCell* cell = [self autocompleteTextFieldCell];
+ return [cell starIconFrameForFrame:[self bounds]];
+}
+
+- (NSPasteboard*)locationDragPasteboard {
+ return [[self autocompleteTextFieldCell] locationDragPasteboard];
+}
+
@end
diff --git a/chrome/browser/cocoa/autocomplete_text_field_cell.h b/chrome/browser/cocoa/autocomplete_text_field_cell.h
index 1e0a3c5..bc791cf 100644
--- a/chrome/browser/cocoa/autocomplete_text_field_cell.h
+++ b/chrome/browser/cocoa/autocomplete_text_field_cell.h
@@ -13,7 +13,15 @@ class ExtensionAction;
// Holds a |LocationBarImageView| and its current rect. Do not keep references
// to this object, only use it directly after calling |-layedOutIcons:|.
+// TODO(shess): This class is basically a helper for laying out the
+// icons. Try to refactor it away. If that is not reasonable, at
+// least split the image and label cases into subclasses once the
+// Omnibox stuff is settled.
@interface AutocompleteTextFieldIcon : NSObject {
+ // YES to draw the label part of |view_|, otherwise draw the image
+ // part.
+ BOOL isLabel_;
+
// The frame rect of |view_|.
NSRect rect_;
@@ -21,12 +29,20 @@ class ExtensionAction;
LocationBarViewMac::LocationBarImageView* view_;
}
-// Returns a new AutocompleteTextFieldIcon object.
-+ (AutocompleteTextFieldIcon*)
- iconWithRect:(NSRect)rect
- view:(LocationBarViewMac::LocationBarImageView*)view;
@property(assign, nonatomic) NSRect rect;
@property(assign, nonatomic) LocationBarViewMac::LocationBarImageView* view;
+
+- (id)initImageWithView:(LocationBarViewMac::LocationBarImageView*)view;
+- (id)initLabelWithView:(LocationBarViewMac::LocationBarImageView*)view;
+
+// Position |view_| right-justified in |frame|.
+- (void)positionInFrame:(NSRect)frame;
+
+// Draw image or label of |view_| in |rect_| within |controlView|.
+// Only call after |-positionInFrame:| has set |rect_| (or after an
+// explicit |-setRect:|).
+- (void)drawInView:(NSView*)controlView;
+
@end
// AutocompleteTextFieldCell extends StyledTextFieldCell to provide support for
@@ -44,10 +60,17 @@ class ExtensionAction;
// side of the field. Exclusive WRT |keywordString_|;
scoped_nsobject<NSAttributedString> hintString_;
- // View showing the state of the SSL connection. Owned by the location bar.
- // Display is exclusive WRT the |hintString_| and |keywordString_|.
- // This may be NULL during testing.
- LocationBarViewMac::SecurityImageView* security_image_view_;
+ // The location icon sits at the left-hand side of the field.
+ // |keywordString_| overrides.
+ LocationBarViewMac::LocationIconView* locationIconView_;
+
+ // The star icon sits at the right-hand side of the field when an
+ // URL is being shown.
+ LocationBarViewMac::LocationBarImageView* starIconView_;
+
+ // The security label floats to the left of page actions at the
+ // right-hand side.
+ LocationBarViewMac::LocationBarImageView* securityLabelView_;
// List of views showing visible Page Actions. Owned by the location bar.
// Display is exclusive WRT the |hintString_| and |keywordString_|.
@@ -77,34 +100,58 @@ class ExtensionAction;
availableWidth:(CGFloat)width;
- (void)clearKeywordAndHint;
-- (void)setSecurityImageView:(LocationBarViewMac::SecurityImageView*)view;
+- (void)setLocationIconView:(LocationBarViewMac::LocationIconView*)view;
+- (void)setStarIconView:(LocationBarViewMac::LocationBarImageView*)view;
+- (void)setSecurityLabelView:(LocationBarViewMac::LocationBarImageView*)view;
- (void)setPageActionViewList:(LocationBarViewMac::PageActionViewList*)list;
- (void)setContentSettingViewsList:
(LocationBarViewMac::ContentSettingViews*)views;
+// Returns the portion of the cell to use for displaying the location
+// icon.
+- (NSRect)locationIconFrameForFrame:(NSRect)cellFrame;
+
// Returns an array of the visible AutocompleteTextFieldIcon objects. Returns
// only visible icons.
- (NSArray*)layedOutIcons:(NSRect)cellFrame;
+// Return the rectangle the star is being shown in, for purposes of
+// positioning the bookmark bubble.
+- (NSRect)starIconFrameForFrame:(NSRect)cellFrame;
+
+// Returns the portion of the cell to use for displaying the Page
+// Action icon at the given index. May be NSZeroRect if the index's
+// action is not visible. This does a linear walk over all page
+// actions, so do not call this in a loop to get the position of all
+// page actions. Use |-layedOutIcons:| instead in that case.
+- (NSRect)pageActionFrameForIndex:(size_t)index inFrame:(NSRect)cellFrame;
// Similar to |pageActionFrameForIndex:inFrame| but accepts an
// ExtensionAction for when the index is not known.
- (NSRect)pageActionFrameForExtensionAction:(ExtensionAction*)action
inFrame:(NSRect)cellFrame;
-// Returns the portion of the cell to use for displaying the Page Action icon
-// at the given index. May be NSZeroRect if the index's action is not visible.
-// This does a linear walk over all page actions, so do not call this in a loop
-// to get the position of all page actions. Use |-layedOutIcons:| instead in that
-// case.
-- (NSRect)pageActionFrameForIndex:(size_t)index inFrame:(NSRect)cellFrame;
+// Find the icon under the event. |nil| if |theEvent| is not over
+// anything.
+- (AutocompleteTextFieldIcon*)iconForEvent:(NSEvent*)theEvent
+ inRect:(NSRect)cellFrame
+ ofView:(AutocompleteTextField*)controlView;
// Return the appropriate menu for any page actions under event.
// Returns nil if no menu is present for the action, or if the event
// is not over an action.
-- (NSMenu*)actionMenuForEvent:(NSEvent*)event
+- (NSMenu*)actionMenuForEvent:(NSEvent*)theEvent
inRect:(NSRect)cellFrame
- ofView:(NSView*)aView;
+ ofView:(AutocompleteTextField*)controlView;
+
+// Called by |AutocompleteTextField| to let page actions intercept
+// clicks. Returns |YES| if the click has been intercepted.
+- (BOOL)mouseDown:(NSEvent*)theEvent
+ inRect:(NSRect)cellFrame
+ ofView:(AutocompleteTextField*)controlView;
+
+// If the location icon is draggable, return its drag pasteboard.
+- (NSPasteboard*)locationDragPasteboard;
@end
@@ -118,8 +165,4 @@ class ExtensionAction;
// Returns the total number of installed Page Actions, visible or not.
- (size_t)pageActionCount;
-// Returns the portion of the cell to use for displaying the security (SSL lock)
-// icon, leaving space for its label if any.
-- (NSRect)securityImageFrameForFrame:(NSRect)cellFrame;
-
@end
diff --git a/chrome/browser/cocoa/autocomplete_text_field_cell.mm b/chrome/browser/cocoa/autocomplete_text_field_cell.mm
index 7b7f35c..9801892 100644
--- a/chrome/browser/cocoa/autocomplete_text_field_cell.mm
+++ b/chrome/browser/cocoa/autocomplete_text_field_cell.mm
@@ -7,6 +7,20 @@
#include "app/resource_bundle.h"
#include "base/logging.h"
#include "gfx/font.h"
+#include "grit/theme_resources.h"
+
+@interface AutocompleteTextAttachmentCell : NSTextAttachmentCell {
+}
+
+// TODO(shess):
+// Override -cellBaselineOffset to allow the image to be shifted up or
+// down relative to the containing text's baseline.
+
+// Draw the image using |DrawImageInRect()| helper function for
+// |-setFlipped:| consistency with other image drawing.
+- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)aView;
+
+@end
namespace {
@@ -35,16 +49,28 @@ 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 = -5;
+
// The amount of padding on either side reserved for drawing an icon.
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;
+// Cause the location icon to line up above the icons in the popup.
+const CGFloat kLocationIconXOffset = 6.0;
+const CGFloat kLocationIconXPad = 1.0;
+
+// How long to wait for mouse-up on the location icon before assuming
+// that the user wants to drag.
+const NSTimeInterval kLocationIconDragTimeout = 0.25;
+
// Conveniences to centralize width+offset calculations.
CGFloat WidthForHint(NSAttributedString* hintString) {
return kHintXOffset + ceil([hintString size].width);
@@ -54,20 +80,103 @@ 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) {
+ // If there is an image, make sure we calculated the target size
+ // correctly.
+ DCHECK(!image || NSEqualSizes([image size], rect.size));
+ [image setFlipped:[view isFlipped]];
+ [image drawInRect:rect
+ fromRect:NSZeroRect // Entire image
+ operation:NSCompositeSourceOver
+ 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<AutocompleteTextAttachmentCell> attachmentCell(
+ [[AutocompleteTextAttachmentCell 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 AutocompleteTextAttachmentCell
+
+- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)aView {
+ // Draw image with |DrawImageInRect()| to get consistent
+ // |-setFlipped:| treatment.
+ DrawImageInRect([self image], aView, cellFrame);
+}
+
+@end
+
@implementation AutocompleteTextFieldIcon
@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
@@ -96,18 +205,40 @@ CGFloat WidthForKeyword(NSAttributedString* keywordString) {
// 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.
+ NSImage* image =
+ AutocompleteEditViewMac::ImageForResource(IDR_OMNIBOX_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
@@ -155,21 +286,8 @@ CGFloat WidthForKeyword(NSAttributedString* keywordString) {
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]];
@@ -213,8 +331,16 @@ CGFloat WidthForKeyword(NSAttributedString* keywordString) {
page_action_views_ = list;
}
-- (void)setSecurityImageView:(LocationBarViewMac::SecurityImageView*)view {
- security_image_view_ = view;
+- (void)setLocationIconView:(LocationBarViewMac::LocationIconView*)view {
+ locationIconView_ = view;
+}
+
+- (void)setStarIconView:(LocationBarViewMac::LocationBarImageView*)view {
+ starIconView_ = view;
+}
+
+- (void)setSecurityLabelView:(LocationBarViewMac::LocationBarImageView*)view {
+ securityLabelView_ = view;
}
- (void)setContentSettingViewsList:
@@ -226,69 +352,81 @@ CGFloat WidthForKeyword(NSAttributedString* keywordString) {
- (NSRect)textFrameForFrame:(NSRect)cellFrame {
NSRect textFrame([super textFrameForFrame:cellFrame]);
- if (hintString_) {
+ // NOTE: This function must closely match the logic in
+ // |-drawInteriorWithFrame:inView:|.
+
+ // Location icon is not shown in keyword search mode.
+ if (!keywordString_ && locationIconView_ && locationIconView_->IsVisible()) {
+ const NSRect iconFrame = [self locationIconFrameForFrame:cellFrame];
+ const CGFloat newOrigin = NSMaxX(iconFrame) + kLocationIconXPad;
+ textFrame.size.width = NSMaxX(textFrame) - newOrigin;
+ textFrame.origin.x = newOrigin;
+ }
+
+ // 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* icons = [self layedOutIcons:cellFrame];
+ if ([icons count]) {
+ // Max x for resulting text frame.
+ const CGFloat maxX = NSMinX([[icons objectAtIndex:0] rect]);
+ textFrame.size.width = maxX - NSMinX(textFrame);
+ }
+
+ // Keyword string or hint string if they fit.
+ if (keywordString_) {
+ DCHECK(!hintString_);
+ const CGFloat keywordWidth(WidthForKeyword(keywordString_));
+
+ if (keywordWidth < NSWidth(textFrame)) {
+ textFrame.origin.x += keywordWidth;
+ textFrame.size.width -= keywordWidth;
+ }
+ } else 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)) {
- textFrame.origin.x += keywordWidth;
- textFrame.size.width = NSMaxX(cellFrame) - NSMinX(textFrame);
+ // SSL label if it fits.
+ if (securityLabelView_ && securityLabelView_->IsVisible() &&
+ securityLabelView_->GetLabel()) {
+ NSAttributedString* label = securityLabelView_->GetLabel();
+ const CGFloat labelWidth = ceil([label size].width) + kIconHorizontalPad;
+ if (NSWidth(textFrame) > labelWidth) {
+ textFrame.size.width -= labelWidth;
}
- } else {
- // Leave room for images on the right (lock icon etc).
- 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;
}
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 (!locationIconView_ || !locationIconView_->IsVisible())
+ return NSZeroRect;
+
+ 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);
}
-- (NSRect)securityImageFrameForFrame:(NSRect)cellFrame {
- if (!security_image_view_ || !security_image_view_->IsVisible()) {
+- (NSRect)starIconFrameForFrame:(NSRect)cellFrame {
+ if (!starIconView_ || !starIconView_->IsVisible())
return NSZeroRect;
- }
-
- // Calculate the total width occupied by the image, label, and padding.
- NSSize imageSize = [security_image_view_->GetImage() size];
- CGFloat widthUsed = imageSize.width + kIconHorizontalPad;
- NSAttributedString* label = security_image_view_->GetLabel();
- if (label) {
- widthUsed += ceil([label size].width) + kHintXOffset;
- }
- return [self rightJustifyImage:imageSize
- inRect:cellFrame
- withMargin:widthUsed];
+ // The star icon is always at the RHS.
+ scoped_nsobject<AutocompleteTextFieldIcon> icon(
+ [[AutocompleteTextFieldIcon alloc] initImageWithView:starIconView_]);
+ cellFrame.size.width -= kHintXOffset;
+ [icon positionInFrame:cellFrame];
+ return [icon rect];
}
- (size_t)pageActionCount {
@@ -365,118 +503,223 @@ CGFloat WidthForKeyword(NSAttributedString* keywordString) {
[path stroke];
// Draw text w/in the rectangle.
- infoFrame.origin.x += 4.0;
- infoFrame.origin.y += 1.0;
+ infoFrame.origin.x += 3.0;
[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 {
+ NSRect workingFrame = cellFrame;
+
+ // NOTE: This function must closely match the logic in
+ // |-textFrameForFrame:|.
+
+ // Location icon is not shown in keyword search mode.
+ if (!keywordString_ && locationIconView_ && locationIconView_->IsVisible()) {
+ const NSRect iconFrame = [self locationIconFrameForFrame:cellFrame];
+ DrawImageInRect(locationIconView_->GetImage(), controlView, iconFrame);
+ const CGFloat newOrigin = NSMaxX(iconFrame) + kLocationIconXPad;
+ workingFrame.size.width = NSMaxX(workingFrame) - newOrigin;
+ workingFrame.origin.x = newOrigin;
}
- // 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];
-}
+ NSArray* icons = [self layedOutIcons:cellFrame];
+ for (AutocompleteTextFieldIcon* icon in icons) {
+ [icon drawInView:controlView];
+ }
+ if ([icons count]) {
+ // Max x for resulting text frame.
+ const CGFloat maxX = NSMinX([[icons objectAtIndex:0] rect]);
+ workingFrame.size.width = maxX - NSMinX(workingFrame);
+ }
-- (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];
+ // Keyword string or hint string if they fit.
+ if (keywordString_) {
+ DCHECK(!hintString_);
+ const CGFloat keywordWidth(WidthForKeyword(keywordString_));
+
+ if (keywordWidth < NSWidth(workingFrame)) {
+ [self drawKeywordWithFrame:cellFrame inView:controlView];
+ workingFrame.origin.x += keywordWidth;
+ workingFrame.size.width -= keywordWidth;
+ }
+ } else 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(workingFrame)) {
+ [self drawHintWithFrame:cellFrame inView:controlView];
+ workingFrame.size.width -= hintWidth;
}
}
+ // SSL label if it fits.
+ if (securityLabelView_ && securityLabelView_->IsVisible() &&
+ securityLabelView_->GetLabel()) {
+ NSAttributedString* label = securityLabelView_->GetLabel();
+ const CGFloat labelWidth = ceil([label size].width) + kIconHorizontalPad;
+ if (NSWidth(workingFrame) > labelWidth) {
+ workingFrame.size.width -= kIconHorizontalPad;
+
+ scoped_nsobject<AutocompleteTextFieldIcon> icon(
+ [[AutocompleteTextFieldIcon alloc]
+ initLabelWithView:securityLabelView_]);
+ [icon positionInFrame:workingFrame];
+ [icon drawInView:controlView];
+ DCHECK_EQ(labelWidth, NSWidth([icon rect]) + kIconHorizontalPad);
+ workingFrame.size.width -= NSWidth([icon rect]);
+ }
+ }
+
+ // Superclass draws text portion WRT original |cellFrame|.
[super drawInteriorWithFrame:cellFrame inView:controlView];
}
- (NSArray*)layedOutIcons:(NSRect)cellFrame {
- NSMutableArray* result = [NSMutableArray arrayWithCapacity:0];
- NSRect iconFrame = cellFrame;
- if (security_image_view_ && security_image_view_->IsVisible()) {
- NSRect securityImageFrame = [self securityImageFrameForFrame:iconFrame];
- [result addObject:
- [AutocompleteTextFieldIcon iconWithRect:securityImageFrame
- view:security_image_view_]];
- iconFrame.size.width -= NSMaxX(iconFrame) - NSMinX(securityImageFrame);
+ // The set of views to display right-justified in the cell, from
+ // left to right.
+ NSMutableArray* result = [NSMutableArray array];
+
+ // 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_) {
+ views.insert(views.end(),
+ content_setting_views_->begin(),
+ content_setting_views_->end());
}
- 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);
- }
+ // 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));
}
- 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);
- }
+ // The star icon should always come last.
+ if (starIconView_)
+ views.push_back(starIconView_);
+
+ // 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)
+ return NO;
+
+ // If the icon is draggable, then initiate a drag if the user drags
+ // or holds the mouse down for awhile.
+ if ([icon view]->IsDraggable()) {
+ NSDate* timeout =
+ [NSDate dateWithTimeIntervalSinceNow:kLocationIconDragTimeout];
+ NSEvent* event = [NSApp nextEventMatchingMask:(NSLeftMouseDraggedMask |
+ NSLeftMouseUpMask)
+ untilDate:timeout
+ inMode:NSEventTrackingRunLoopMode
+ dequeue:YES];
+ if (!event || [event type] == NSLeftMouseDragged) {
+ NSPasteboard* pboard = [icon view]->GetDragPasteboard();
+ DCHECK(pboard);
+
+ // TODO(shess): My understanding is that the -isFlipped
+ // adjustment should not be necessary. But without it, the
+ // image is nowhere near the cursor. Perhaps the icon's rect is
+ // incorrectly calculated?
+ // http://crbug.com/40711
+ NSPoint dragPoint = [icon rect].origin;
+ if ([controlView isFlipped])
+ dragPoint.y += NSHeight([icon rect]);
+
+ [controlView dragImage:[icon view]->GetImage()
+ at:dragPoint
+ offset:NSZeroSize
+ event:event ? event : theEvent
+ pasteboard:pboard
+ source:self
+ slideBack:YES];
+ return YES;
}
+
+ // On mouse-up fall through to mouse-pressed case.
+ DCHECK_EQ([event type], NSLeftMouseUp);
}
+
+ [icon view]->OnMousePressed([icon rect]);
+ return YES;
+}
+
+- (NSDragOperation)draggingSourceOperationMaskForLocal:(BOOL)isLocal {
+ return NSDragOperationCopy;
+}
+
+- (NSPasteboard*)locationDragPasteboard {
+ if (locationIconView_ && locationIconView_->IsDraggable())
+ return locationIconView_->GetDragPasteboard();
+
return nil;
}
diff --git a/chrome/browser/cocoa/autocomplete_text_field_cell_unittest.mm b/chrome/browser/cocoa/autocomplete_text_field_cell_unittest.mm
index 0a16c48..5bd02cc 100644
--- a/chrome/browser/cocoa/autocomplete_text_field_cell_unittest.mm
+++ b/chrome/browser/cocoa/autocomplete_text_field_cell_unittest.mm
@@ -4,9 +4,11 @@
#import <Cocoa/Cocoa.h>
+#include "app/resource_bundle.h"
#include "base/scoped_nsobject.h"
#import "chrome/browser/cocoa/autocomplete_text_field_cell.h"
#import "chrome/browser/cocoa/cocoa_test_helper.h"
+#include "grit/theme_resources.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"
@@ -43,7 +45,7 @@ class TestPageActionViewList : public LocationBarViewMac::PageActionViewList {
class AutocompleteTextFieldCellTest : public CocoaTest {
public:
- AutocompleteTextFieldCellTest() : security_image_view_(NULL, NULL, NULL),
+ AutocompleteTextFieldCellTest() : location_icon_view_(NULL),
page_action_views_() {
// Make sure this is wide enough to play games with the cell
// decorations.
@@ -57,7 +59,8 @@ class AutocompleteTextFieldCellTest : public CocoaTest {
[[AutocompleteTextFieldCell alloc] initTextCell:@"Testing"]);
[cell setEditable:YES];
[cell setBordered:YES];
- [cell setSecurityImageView:&security_image_view_];
+ [cell setLocationIconView:&location_icon_view_];
+ [cell setSecurityLabelView:&security_label_view_];
[cell setPageActionViewList:&page_action_views_];
[view_ setCell:cell.get()];
@@ -65,7 +68,8 @@ class AutocompleteTextFieldCellTest : public CocoaTest {
}
NSTextField* view_;
- LocationBarViewMac::SecurityImageView security_image_view_;
+ LocationBarViewMac::LocationIconView location_icon_view_;
+ LocationBarViewMac::LocationBarImageView security_label_view_;
TestPageActionViewList page_action_views_;
};
@@ -199,15 +203,16 @@ TEST_F(AutocompleteTextFieldCellTest, TextFrame) {
EXPECT_EQ(NSMaxX(bounds), NSMaxX(textFrame));
EXPECT_TRUE(NSContainsRect(cursorFrame, textFrame));
- // Security icon takes up space on the right
- security_image_view_.SetImageShown(
- LocationBarViewMac::SecurityImageView::LOCK);
- security_image_view_.SetVisible(true);
+ // Location icon takes up space on the left
+ location_icon_view_.SetImage(
+ ResourceBundle::GetSharedInstance().GetNSImageNamed(
+ IDR_OMNIBOX_HTTPS_VALID));
+ location_icon_view_.SetVisible(true);
textFrame = [cell textFrameForFrame:bounds];
EXPECT_FALSE(NSIsEmptyRect(textFrame));
EXPECT_TRUE(NSContainsRect(bounds, textFrame));
- EXPECT_LT(NSMaxX(textFrame), NSMaxX(bounds));
+ EXPECT_GT(NSMinX(textFrame), NSMinX(bounds));
EXPECT_TRUE(NSContainsRect(cursorFrame, textFrame));
// Search hint text takes precedence over the hint icon; the text frame
@@ -265,9 +270,10 @@ TEST_F(AutocompleteTextFieldCellTest, DrawingRectForBounds) {
EXPECT_TRUE(NSContainsRect(NSInsetRect(textFrame, 1, 1), drawingRect));
EXPECT_TRUE(NSEqualRects(drawingRect, originalDrawingRect));
- security_image_view_.SetImageShown(
- LocationBarViewMac::SecurityImageView::LOCK);
- security_image_view_.SetVisible(true);
+ location_icon_view_.SetImage(
+ ResourceBundle::GetSharedInstance().GetNSImageNamed(
+ IDR_OMNIBOX_HTTPS_VALID));
+ location_icon_view_.SetVisible(true);
textFrame = [cell textFrameForFrame:bounds];
drawingRect = [cell drawingRectForBounds:bounds];
@@ -275,55 +281,60 @@ TEST_F(AutocompleteTextFieldCellTest, DrawingRectForBounds) {
EXPECT_TRUE(NSContainsRect(NSInsetRect(textFrame, 1, 1), drawingRect));
}
-// Test that the security icon is at the right side of the cell.
-TEST_F(AutocompleteTextFieldCellTest, SecurityImageFrame) {
+// Test that the location icon is at the right side of the cell.
+TEST_F(AutocompleteTextFieldCellTest, LocationIconFrame) {
AutocompleteTextFieldCell* cell =
static_cast<AutocompleteTextFieldCell*>([view_ cell]);
const NSRect bounds([view_ bounds]);
- security_image_view_.SetImageShown(
- LocationBarViewMac::SecurityImageView::LOCK);
-
- security_image_view_.SetVisible(false);
- EXPECT_EQ(0u, [[cell layedOutIcons:bounds] count]);
-
- security_image_view_.SetVisible(true);
- NSArray* icons = [cell layedOutIcons:bounds];
- ASSERT_EQ(1u, [icons count]);
- NSRect iconRect = [[icons objectAtIndex:0] rect];
+ location_icon_view_.SetImage(
+ ResourceBundle::GetSharedInstance().GetNSImageNamed(
+ IDR_OMNIBOX_HTTPS_VALID));
+ location_icon_view_.SetVisible(true);
+ const NSRect iconRect = [cell locationIconFrameForFrame:bounds];
EXPECT_FALSE(NSIsEmptyRect(iconRect));
EXPECT_TRUE(NSContainsRect(bounds, iconRect));
- // Make sure we are right of the |drawingRect|.
- NSRect drawingRect = [cell drawingRectForBounds:bounds];
- EXPECT_LE(NSMaxX(drawingRect), NSMinX(iconRect));
+ // Location icon should be left of |drawingRect|.
+ const NSRect drawingRect = [cell drawingRectForBounds:bounds];
+ EXPECT_GT(NSMinX(drawingRect), NSMinX(iconRect));
- // Make sure we're right of the |textFrame|.
- NSRect textFrame = [cell textFrameForFrame:bounds];
- EXPECT_LE(NSMaxX(textFrame), NSMinX(iconRect));
+ // Location icon should be left of |textFrame|.
+ const NSRect textFrame = [cell textFrameForFrame:bounds];
+ EXPECT_GT(NSMinX(textFrame), NSMinX(iconRect));
+}
+
+// Test that security label takes space to the right.
+TEST_F(AutocompleteTextFieldCellTest, SecurityLabelFrame) {
+ AutocompleteTextFieldCell* cell =
+ static_cast<AutocompleteTextFieldCell*>([view_ cell]);
+ const NSRect bounds([view_ bounds]);
+
+ // No label shows nothing, regardless of visibility setting.
+ security_label_view_.SetVisible(false);
+ const NSRect baseTextFrame = [cell textFrameForFrame:bounds];
+ security_label_view_.SetVisible(true);
+ EXPECT_TRUE(NSEqualRects(baseTextFrame, [cell textFrameForFrame:bounds]));
- // Now add a label.
+ // Still not visible even with a label.
NSFont* font = [NSFont controlContentFontOfSize:12.0];
NSColor* color = [NSColor blackColor];
- security_image_view_.SetLabel(@"Label", font, color);
- icons = [cell layedOutIcons:bounds];
- ASSERT_EQ(1u, [icons count]);
- iconRect = [[icons objectAtIndex:0] rect];
+ security_label_view_.SetLabel(@"Label", font, color);
+ security_label_view_.SetVisible(false);
+ EXPECT_TRUE(NSEqualRects(baseTextFrame, [cell textFrameForFrame:bounds]));
- EXPECT_FALSE(NSIsEmptyRect(iconRect));
- EXPECT_TRUE(NSContainsRect(bounds, iconRect));
-
- // Make sure we are right of the |drawingRect|.
- drawingRect = [cell drawingRectForBounds:bounds];
- EXPECT_LE(NSMaxX(drawingRect), NSMinX(iconRect));
+ // Visible with a label is strictly narrower than without.
+ security_label_view_.SetVisible(true);
+ NSRect textFrame = [cell textFrameForFrame:bounds];
+ const CGFloat labelWidth = [security_label_view_.GetLabel() size].width;
+ EXPECT_TRUE(NSContainsRect(baseTextFrame, textFrame));
+ EXPECT_LT(NSWidth(textFrame), NSWidth(baseTextFrame) - labelWidth);
- // Make sure we're right of the |textFrame|.
+ NSString* longLabel =
+ @"Really super-long labels will not show up if there's not enough room.";
+ security_label_view_.SetLabel(longLabel, font, color);
textFrame = [cell textFrameForFrame:bounds];
- EXPECT_LE(NSMaxX(textFrame), NSMinX(iconRect));
-
- // Make sure we clear correctly.
- security_image_view_.SetVisible(false);
- EXPECT_EQ(0u, [[cell layedOutIcons:bounds] count]);
+ EXPECT_TRUE(NSEqualRects(baseTextFrame, [cell textFrameForFrame:bounds]));
}
// Test Page Action counts.
@@ -349,8 +360,6 @@ TEST_F(AutocompleteTextFieldCellTest, PageActionImageFrame) {
AutocompleteTextFieldCell* cell =
static_cast<AutocompleteTextFieldCell*>([view_ cell]);
const NSRect bounds([view_ bounds]);
- security_image_view_.SetImageShown(
- LocationBarViewMac::SecurityImageView::LOCK);
TestPageActionImageView page_action_view;
// We'll assume that the extensions code enforces icons smaller than the
@@ -368,13 +377,12 @@ TEST_F(AutocompleteTextFieldCellTest, PageActionImageFrame) {
list.Add(&page_action_view2);
[cell setPageActionViewList:&list];
- security_image_view_.SetVisible(false);
page_action_view.SetVisible(false);
page_action_view2.SetVisible(false);
EXPECT_TRUE(NSIsEmptyRect([cell pageActionFrameForIndex:0 inFrame:bounds]));
EXPECT_TRUE(NSIsEmptyRect([cell pageActionFrameForIndex:1 inFrame:bounds]));
- // One page action, no security icon.
+ // One page action, no lock icon.
page_action_view.SetVisible(true);
NSRect iconRect0 = [cell pageActionFrameForIndex:0 inFrame:bounds];
@@ -389,17 +397,19 @@ TEST_F(AutocompleteTextFieldCellTest, PageActionImageFrame) {
NSRect textFrame = [cell textFrameForFrame:bounds];
EXPECT_LE(NSMaxX(textFrame), NSMinX(iconRect0));
- // Two page actions plus a security icon.
+ // Two page actions plus a security label.
page_action_view2.SetVisible(true);
- security_image_view_.SetVisible(true);
NSArray* icons = [cell layedOutIcons:bounds];
- EXPECT_EQ(3u, [icons count]);
+ ASSERT_EQ(2u, [icons count]);
+
+ // TODO(shess): page-action list is inverted from -layedOutIcons:
+ // Yes, this is confusing, fix it.
iconRect0 = [cell pageActionFrameForIndex:0 inFrame:bounds];
NSRect iconRect1 = [cell pageActionFrameForIndex:1 inFrame:bounds];
- NSRect lockRect = [[icons objectAtIndex:0] rect];
+ NSRect labelRect = [[icons objectAtIndex:0] rect];
EXPECT_TRUE(NSEqualRects(iconRect0, [[icons objectAtIndex:1] rect]));
- EXPECT_TRUE(NSEqualRects(iconRect1, [[icons objectAtIndex:2] rect]));
+ EXPECT_TRUE(NSEqualRects(iconRect1, [[icons objectAtIndex:0] rect]));
// Make sure they're all in the expected order, and right of the |drawingRect|
// and |textFrame|.
@@ -410,13 +420,13 @@ TEST_F(AutocompleteTextFieldCellTest, PageActionImageFrame) {
EXPECT_TRUE(NSContainsRect(bounds, iconRect0));
EXPECT_FALSE(NSIsEmptyRect(iconRect1));
EXPECT_TRUE(NSContainsRect(bounds, iconRect1));
- EXPECT_FALSE(NSIsEmptyRect(lockRect));
- EXPECT_TRUE(NSContainsRect(bounds, lockRect));
+ EXPECT_FALSE(NSIsEmptyRect(labelRect));
+ EXPECT_TRUE(NSContainsRect(bounds, labelRect));
EXPECT_LE(NSMaxX(drawingRect), NSMinX(iconRect1));
EXPECT_LE(NSMaxX(textFrame), NSMinX(iconRect1));
EXPECT_LE(NSMaxX(iconRect1), NSMinX(iconRect0));
- EXPECT_LE(NSMaxX(iconRect0), NSMinX(lockRect));
+ EXPECT_LE(NSMaxX(labelRect), NSMinX(iconRect0));
}
// Test that the cell correctly chooses the partial keyword if there's
@@ -428,11 +438,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/autocomplete_text_field_editor.mm b/chrome/browser/cocoa/autocomplete_text_field_editor.mm
index 70aa5cd..974b346 100644
--- a/chrome/browser/cocoa/autocomplete_text_field_editor.mm
+++ b/chrome/browser/cocoa/autocomplete_text_field_editor.mm
@@ -33,6 +33,35 @@ class Extension;
return self;
}
+// If the entire field is selected, drag the same data as would be
+// dragged from the field's location icon. In some cases the textual
+// contents will not contain relevant data (for instance, "http://" is
+// stripped from URLs).
+- (BOOL)dragSelectionWithEvent:(NSEvent *)event
+ offset:(NSSize)mouseOffset
+ slideBack:(BOOL)slideBack {
+ const NSRange allRange = NSMakeRange(0, [[self textStorage] length]);
+ if (NSEqualRanges(allRange, [self selectedRange])) {
+ NSPasteboard* pboard = [[self delegate] locationDragPasteboard];
+ if (pboard) {
+ NSPoint p;
+ NSImage* image = [self dragImageForSelectionWithEvent:event origin:&p];
+
+ [self dragImage:image
+ at:p
+ offset:mouseOffset
+ event:event
+ pasteboard:pboard
+ source:self
+ slideBack:slideBack];
+ return YES;
+ }
+ }
+ return [super dragSelectionWithEvent:event
+ offset:mouseOffset
+ slideBack:slideBack];
+}
+
- (void)copy:(id)sender {
AutocompleteTextFieldObserver* observer = [self observer];
DCHECK(observer);
diff --git a/chrome/browser/cocoa/autocomplete_text_field_unittest.mm b/chrome/browser/cocoa/autocomplete_text_field_unittest.mm
index d695f86..1d0ae49 100644
--- a/chrome/browser/cocoa/autocomplete_text_field_unittest.mm
+++ b/chrome/browser/cocoa/autocomplete_text_field_unittest.mm
@@ -4,6 +4,7 @@
#import <Cocoa/Cocoa.h>
+#include "app/resource_bundle.h"
#import "base/cocoa_protocols_mac.h"
#include "base/scoped_nsobject.h"
#import "chrome/browser/cocoa/autocomplete_text_field.h"
@@ -11,6 +12,7 @@
#import "chrome/browser/cocoa/autocomplete_text_field_editor.h"
#import "chrome/browser/cocoa/autocomplete_text_field_unittest_helper.h"
#import "chrome/browser/cocoa/cocoa_test_helper.h"
+#include "grit/theme_resources.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"
@@ -20,18 +22,34 @@ using ::testing::Return;
using ::testing::StrictMock;
namespace {
-class MockSecurityImageView : public LocationBarViewMac::SecurityImageView {
+class MockLocationIconView : public LocationBarViewMac::LocationIconView {
public:
- MockSecurityImageView(LocationBarViewMac* owner,
- Profile* profile,
- ToolbarModel* model)
- : LocationBarViewMac::SecurityImageView(owner, profile, model) {}
+ MockLocationIconView()
+ : LocationBarViewMac::LocationIconView(NULL),
+ is_draggable_(false),
+ mouse_was_pressed_(false) {}
+
+ // |LocationBarViewMac::LocationIconView| dragging support needs
+ // more setup than this test provides.
+ bool IsDraggable() {
+ return is_draggable_;
+ }
+ virtual NSPasteboard* GetDragPasteboard() {
+ return [NSPasteboard pasteboardWithUniqueName];
+ }
+ void SetDraggable(bool is_draggable) {
+ is_draggable_ = is_draggable;
+ }
// We can't use gmock's MOCK_METHOD macro, because it doesn't like the
// NSRect argument to OnMousePressed.
virtual void OnMousePressed(NSRect bounds) {
mouse_was_pressed_ = true;
}
+ bool MouseWasPressed() { return mouse_was_pressed_; }
+
+ private:
+ bool is_draggable_;
bool mouse_was_pressed_;
};
@@ -582,32 +600,35 @@ TEST_F(AutocompleteTextFieldTest, TripleClickSelectsAll) {
}
// Clicking the security icon should call its OnMousePressed.
-TEST_F(AutocompleteTextFieldObserverTest, SecurityIconMouseDown) {
+TEST_F(AutocompleteTextFieldTest, LocationIconMouseDown) {
AutocompleteTextFieldCell* cell = [field_ autocompleteTextFieldCell];
- MockSecurityImageView security_image_view(NULL, NULL, NULL);
- [cell setSecurityImageView:&security_image_view];
- security_image_view.SetImageShown(
- LocationBarViewMac::SecurityImageView::LOCK);
- security_image_view.SetVisible(true);
+ MockLocationIconView location_icon_view;
+ [cell setLocationIconView:&location_icon_view];
+ location_icon_view.SetImage(
+ ResourceBundle::GetSharedInstance().GetNSImageNamed(
+ IDR_OMNIBOX_HTTPS_VALID));
+ location_icon_view.SetVisible(true);
- NSRect iconFrame([cell securityImageFrameForFrame:[field_ bounds]]);
+ NSRect iconFrame([cell locationIconFrameForFrame:[field_ bounds]]);
NSPoint location(NSMakePoint(NSMidX(iconFrame), NSMidY(iconFrame)));
- NSEvent* event(Event(field_, location, NSLeftMouseDown, 1));
+ NSEvent* downEvent(Event(field_, location, NSLeftMouseDown, 1));
+ NSEvent* upEvent(Event(field_, location, NSLeftMouseUp, 1));
- [field_ mouseDown:event];
- EXPECT_TRUE(security_image_view.mouse_was_pressed_);
+ // Since location icon can be dragged, the mouse-press is sent on
+ // mouse-up.
+ [NSApp postEvent:upEvent atStart:YES];
+ [field_ mouseDown:downEvent];
+ EXPECT_TRUE(location_icon_view.MouseWasPressed());
+
+ // TODO(shess): Test that mouse drags are initiated if the next
+ // event is a drag, or if the mouse-up takes too long to arrive.
}
// Clicking a Page Action icon should call its OnMousePressed.
-TEST_F(AutocompleteTextFieldObserverTest, PageActionMouseDown) {
+TEST_F(AutocompleteTextFieldTest, PageActionMouseDown) {
AutocompleteTextFieldCell* cell = [field_ autocompleteTextFieldCell];
- MockSecurityImageView security_image_view(NULL, NULL, NULL);
- security_image_view.SetImageShown(
- LocationBarViewMac::SecurityImageView::LOCK);
- [cell setSecurityImageView:&security_image_view];
-
MockPageActionImageView page_action_view;
NSImage* image = [NSImage imageNamed:@"NSApplicationIcon"];
page_action_view.SetImage(image);
@@ -620,8 +641,7 @@ TEST_F(AutocompleteTextFieldObserverTest, PageActionMouseDown) {
list.Add(&page_action_view2);
[cell setPageActionViewList:&list];
- // One page action, no security lock.
- security_image_view.SetVisible(false);
+ // One page action.
page_action_view.SetVisible(true);
page_action_view2.SetVisible(false);
NSRect iconFrame([cell pageActionFrameForIndex:0 inFrame:[field_ bounds]]);
@@ -631,7 +651,7 @@ TEST_F(AutocompleteTextFieldObserverTest, PageActionMouseDown) {
[field_ mouseDown:event];
EXPECT_TRUE(page_action_view.MouseWasPressed());
- // Two page actions, no security lock.
+ // Two page actions, no lock.
page_action_view2.SetVisible(true);
iconFrame = [cell pageActionFrameForIndex:0 inFrame:[field_ bounds]];
location = NSMakePoint(NSMidX(iconFrame), NSMidY(iconFrame));
@@ -647,8 +667,7 @@ TEST_F(AutocompleteTextFieldObserverTest, PageActionMouseDown) {
[field_ mouseDown:event];
EXPECT_TRUE(page_action_view.MouseWasPressed());
- // Two page actions plus security lock.
- security_image_view.SetVisible(true);
+ // Two page actions.
iconFrame = [cell pageActionFrameForIndex:0 inFrame:[field_ bounds]];
location = NSMakePoint(NSMidX(iconFrame), NSMidY(iconFrame));
event = Event(field_, location, NSLeftMouseDown, 1);
@@ -662,13 +681,6 @@ TEST_F(AutocompleteTextFieldObserverTest, PageActionMouseDown) {
[field_ mouseDown:event];
EXPECT_TRUE(page_action_view.MouseWasPressed());
-
- iconFrame = [cell securityImageFrameForFrame:[field_ bounds]];
- location = NSMakePoint(NSMidX(iconFrame), NSMidY(iconFrame));
- event = Event(field_, location, NSLeftMouseDown, 1);
-
- [field_ mouseDown:event];
- EXPECT_TRUE(security_image_view.mouse_was_pressed_);
}
// Test that page action menus are properly returned.
@@ -860,4 +872,22 @@ TEST_F(AutocompleteTextFieldObserverTest, SendsOnResignKey) {
[test_window() resignKeyWindow];
}
+TEST_F(AutocompleteTextFieldTest, LocationDragPasteboard) {
+ AutocompleteTextFieldCell* cell = [field_ autocompleteTextFieldCell];
+
+ MockLocationIconView location_icon_view;
+ location_icon_view.SetImage(
+ ResourceBundle::GetSharedInstance().GetNSImageNamed(
+ IDR_OMNIBOX_HTTPS_VALID));
+ location_icon_view.SetVisible(true);
+ [cell setLocationIconView:&location_icon_view];
+
+ // Not draggable, so no pasteboard.
+ EXPECT_FALSE([field_ locationDragPasteboard]);
+
+ // Gets a pasteboard when draggable.
+ location_icon_view.SetDraggable(true);
+ EXPECT_TRUE([field_ locationDragPasteboard]);
+}
+
} // namespace
diff --git a/chrome/browser/cocoa/bookmark_bubble_controller.mm b/chrome/browser/cocoa/bookmark_bubble_controller.mm
index fc2ff7b..465691e 100644
--- a/chrome/browser/cocoa/bookmark_bubble_controller.mm
+++ b/chrome/browser/cocoa/bookmark_bubble_controller.mm
@@ -98,7 +98,7 @@
[BrowserWindowController browserWindowControllerForWindow:parentWindow_];
[bwc lockBarVisibilityForOwner:self withAnimation:NO delay:NO];
NSWindow* window = [self window]; // completes nib load
- [bubble_ setArrowLocation:kTopLeft];
+ [bubble_ setArrowLocation:kTopRight];
// Insure decent positioning even in the absence of a browser controller,
// which will occur for some unit tests.
NSPoint arrowtip = bwc ? [bwc pointForBubbleArrowTip] :
diff --git a/chrome/browser/cocoa/browser_test_helper.h b/chrome/browser/cocoa/browser_test_helper.h
index 0420c7a..b7e3e64 100644
--- a/chrome/browser/cocoa/browser_test_helper.h
+++ b/chrome/browser/cocoa/browser_test_helper.h
@@ -25,6 +25,15 @@ class BrowserTestHelper {
profile_.reset(new TestingProfile());
profile_->CreateBookmarkModel(true);
profile_->BlockUntilBookmarkModelLoaded();
+
+ // TODO(shess): These are needed in case someone creates a browser
+ // window off of browser_. pkasting indicates that other
+ // platforms use a stub |BrowserWindow| and thus don't need to do
+ // this.
+ // http://crbug.com/39725
+ profile_->CreateAutocompleteClassifier();
+ profile_->CreateTemplateURLModel();
+
browser_.reset(new Browser(Browser::TYPE_NORMAL, profile_.get()));
}
diff --git a/chrome/browser/cocoa/browser_window_controller.mm b/chrome/browser/cocoa/browser_window_controller.mm
index f482990..d023663 100644
--- a/chrome/browser/cocoa/browser_window_controller.mm
+++ b/chrome/browser/cocoa/browser_window_controller.mm
@@ -1375,7 +1375,7 @@
}
- (NSPoint)pointForBubbleArrowTip {
- NSRect rect = [toolbarController_ starButtonInWindowCoordinates];
+ NSRect rect = [toolbarController_ starIconInWindowCoordinates];
// Determine the point of the arrow of the bubble window.
NSPoint p = rect.origin;
p.x += (NSWidth(rect) / 2.0) + 1.0; // Star is not exactly in center.
diff --git a/chrome/browser/cocoa/browser_window_controller_unittest.mm b/chrome/browser/cocoa/browser_window_controller_unittest.mm
index 5b054fa..d6a3dca 100644
--- a/chrome/browser/cocoa/browser_window_controller_unittest.mm
+++ b/chrome/browser/cocoa/browser_window_controller_unittest.mm
@@ -437,10 +437,10 @@ TEST_F(BrowserWindowControllerTest, TestTopRightForBubble) {
NSPoint p = [controller_ pointForBubbleArrowTip];
NSRect all = [[controller_ window] frame];
- // As a sanity check make sure the point is vaguely in the top left
+ // As a sanity check make sure the point is vaguely in the top right
// of the window.
EXPECT_GT(p.y, all.origin.y + (all.size.height/2));
- EXPECT_LT(p.x, all.origin.x + (all.size.width/2));
+ EXPECT_GT(p.x, all.origin.x + (all.size.width/2));
}
// By the "zoom frame", we mean what Apple calls the "standard frame".
diff --git a/chrome/browser/cocoa/location_bar_view_mac.h b/chrome/browser/cocoa/location_bar_view_mac.h
index 5a82d67..08e1524 100644
--- a/chrome/browser/cocoa/location_bar_view_mac.h
+++ b/chrome/browser/cocoa/location_bar_view_mac.h
@@ -24,7 +24,6 @@
#include "third_party/skia/include/core/SkBitmap.h"
@class AutocompleteTextField;
-class BubblePositioner;
class CommandUpdater;
class ContentSettingImageModel;
@class ExtensionPopupController;
@@ -41,7 +40,6 @@ class LocationBarViewMac : public AutocompleteEditController,
public NotificationObserver {
public:
LocationBarViewMac(AutocompleteTextField* field,
- const BubblePositioner* bubble_positioner,
CommandUpdater* command_updater,
ToolbarModel* toolbar_model,
Profile* profile,
@@ -64,6 +62,9 @@ class LocationBarViewMac : public AutocompleteEditController,
virtual void InvalidatePageActions();
virtual void SaveStateToContents(TabContents* contents);
virtual void Revert();
+ virtual const AutocompleteEditView* location_entry() const {
+ return edit_view_.get();
+ }
virtual AutocompleteEditView* location_entry() {
return edit_view_.get();
}
@@ -76,6 +77,13 @@ class LocationBarViewMac : public AutocompleteEditController,
virtual ExtensionAction* GetVisiblePageAction(size_t index);
virtual void TestPageActionPressed(size_t index);
+ // Set/Get the editable state of the field.
+ void SetEditable(bool editable);
+ bool IsEditable();
+
+ // Set the starred state of the bookmark star.
+ void SetStarred(bool starred);
+
// Updates the location bar. Resets the bar's permanent text and
// security style, and if |should_restore_state| is true, restores
// saved state from the tab (for tab switching).
@@ -124,7 +132,6 @@ class LocationBarViewMac : public AutocompleteEditController,
const std::wstring& keyword,
const std::wstring& short_name,
const bool is_keyword_hint,
- const bool show_search_hint,
NSImage* image);
// Overridden from NotificationObserver.
@@ -142,7 +149,9 @@ class LocationBarViewMac : public AutocompleteEditController,
// Sets the image.
void SetImage(NSImage* image);
- void SetImage(SkBitmap* image);
+
+ // Get the |resource_id| image resource and set the image.
+ void SetIcon(int resource_id);
// Sets the label text, font, and color. |text| may be nil; |color| and
// |font| are ignored if |text| is nil.
@@ -156,9 +165,21 @@ class LocationBarViewMac : public AutocompleteEditController,
const NSAttributedString* GetLabel() const { return label_; }
bool IsVisible() const { return visible_; }
+ // Default size when no image is present.
+ virtual NSSize GetDefaultImageSize() const;
+
+ // Returns the size of the image, else the default size.
+ NSSize GetImageSize() const;
+
// Returns the tooltip for this image view or |nil| if there is none.
virtual const NSString* GetToolTip() { return nil; }
+ // Used to determinate if the item can act as a drag source.
+ virtual bool IsDraggable() { return false; }
+
+ // The drag pasteboard to use if a drag is initiated.
+ virtual NSPasteboard* GetDragPasteboard() { return nil; }
+
// Called on mouse down.
virtual void OnMousePressed(NSRect bounds) {}
@@ -176,42 +197,50 @@ class LocationBarViewMac : public AutocompleteEditController,
DISALLOW_COPY_AND_ASSIGN(LocationBarImageView);
};
- // SecurityImageView is used to display the lock or warning icon when the
- // current URL's scheme is https.
- class SecurityImageView : public LocationBarImageView {
+ // LocationIconView is used to display an icon to the left of the address.
+ class LocationIconView : public LocationBarImageView {
public:
- enum Image {
- LOCK = 0,
- WARNING
- };
+ explicit LocationIconView(LocationBarViewMac* owner);
+ virtual ~LocationIconView();
- SecurityImageView(LocationBarViewMac* owner,
- Profile* profile,
- ToolbarModel* model);
- virtual ~SecurityImageView();
+ // Is draggable if the autocomplete edit view has not be changed.
+ virtual bool IsDraggable();
- // Sets the image to the appropriate icon.
- void SetImageShown(Image image);
+ // Drag the URL and title from the current tab.
+ virtual NSPasteboard* GetDragPasteboard();
// Shows the page info dialog.
virtual void OnMousePressed(NSRect bounds);
private:
- // The lock icon shown when using HTTPS. Loaded lazily, the first time it's
- // needed.
- scoped_nsobject<NSImage> lock_icon_;
-
- // The warning icon shown when HTTPS is broken. Loaded lazily, the first
- // time it's needed.
- scoped_nsobject<NSImage> warning_icon_;
-
// The location bar view that owns us.
LocationBarViewMac* owner_;
- Profile* profile_;
- ToolbarModel* model_;
+ DISALLOW_COPY_AND_ASSIGN(LocationIconView);
+ };
- DISALLOW_COPY_AND_ASSIGN(SecurityImageView);
+ // Used to display the bookmark star in the RHS.
+ class StarIconView : public LocationBarImageView {
+ public:
+ explicit StarIconView(CommandUpdater* command_updater);
+ virtual ~StarIconView() {}
+
+ // Shows the bookmark bubble.
+ virtual void OnMousePressed(NSRect bounds);
+
+ // Set the image and tooltip based on |starred|.
+ void SetStarred(bool starred);
+
+ virtual const NSString* GetToolTip();
+
+ private:
+ // For bringing up bookmark bar.
+ CommandUpdater* command_updater_; // Weak, owned by Browser.
+
+ // The string to show for a tooltip.
+ scoped_nsobject<NSString> tooltip_;
+
+ DISALLOW_COPY_AND_ASSIGN(StarIconView);
};
// PageActionImageView is used to display the icon for a given Page Action
@@ -231,14 +260,13 @@ class LocationBarViewMac : public AutocompleteEditController,
void set_preview_enabled(bool enabled) { preview_enabled_ = enabled; }
- bool preview_enabled() { return preview_enabled_; }
+ bool preview_enabled() const { return preview_enabled_; }
- // Returns the size of the image, or a default size if no image available.
// When a new page action is created, all the icons are destroyed and
// recreated; at this point we need to calculate sizes to lay out the
// icons even though no images are available yet. For this case, we return
// the default image size for a page icon.
- virtual NSSize GetPreferredImageSize();
+ virtual NSSize GetDefaultImageSize() const;
// Either notify listeners or show a popup depending on the Page Action.
virtual void OnMousePressed(NSRect bounds);
@@ -384,11 +412,11 @@ class LocationBarViewMac : public AutocompleteEditController,
};
private:
- // Sets the SSL icon we should be showing.
- void SetSecurityIcon(ToolbarModel::Icon icon);
+ // Sets the location icon we should be showing.
+ void SetIcon(int resource_id);
- // Sets the label for the SSL icon.
- void SetSecurityIconLabel();
+ // Sets the label for the SSL state.
+ void SetSecurityLabel();
// Posts |notification| to the default notification center.
void PostNotification(const NSString* notification);
@@ -411,8 +439,14 @@ class LocationBarViewMac : public AutocompleteEditController,
// The user's desired disposition for how their input should be opened.
WindowOpenDisposition disposition_;
- // The view that shows the lock/warning when in HTTPS mode.
- SecurityImageView security_image_view_;
+ // A view that shows an icon to the left of the address.
+ LocationIconView location_icon_view_;
+
+ // Security info as text which floats left of the page actions.
+ LocationBarImageView security_label_view_;
+
+ // Bookmark star right of page actions.
+ StarIconView star_icon_view_;
// Any installed Page Actions.
PageActionViewList page_action_views_;
diff --git a/chrome/browser/cocoa/location_bar_view_mac.mm b/chrome/browser/cocoa/location_bar_view_mac.mm
index dde3095..35751dc 100644
--- a/chrome/browser/cocoa/location_bar_view_mac.mm
+++ b/chrome/browser/cocoa/location_bar_view_mac.mm
@@ -41,6 +41,7 @@
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
#include "skia/ext/skia_utils_mac.h"
+#import "third_party/mozilla/NSPasteboard+Utils.h"
// TODO(shess): This code is mostly copied from the gtk
@@ -62,11 +63,13 @@ std::wstring GetKeywordName(Profile* profile, const std::wstring& keyword) {
return std::wstring();
}
-// Values for the green text color displayed for EV certificates, based
-// on the values for kEvTextColor in location_bar_view_gtk.cc.
-static const CGFloat kEvTextColorRedComponent = 0.0;
-static const CGFloat kEvTextColorGreenComponent = 0.59;
-static const CGFloat kEvTextColorBlueComponent = 0.08;
+// Values for the label colors for different security states.
+static const CGFloat kEVSecureTextColorRedComponent = 0.03;
+static const CGFloat kEVSecureTextColorGreenComponent = 0.58;
+static const CGFloat kEVSecureTextColorBlueComponent = 0.0;
+static const CGFloat kSecurityErrorTextColorRedComponent = 0.63;
+static const CGFloat kSecurityErrorTextColorGreenComponent = 0.0;
+static const CGFloat kSecurityErrorTextColorBlueComponent = 0.0;
// Build a short string to use in keyword-search when the field isn't
// very big.
@@ -91,17 +94,18 @@ std::wstring CalculateMinString(const std::wstring& description) {
LocationBarViewMac::LocationBarViewMac(
AutocompleteTextField* field,
- const BubblePositioner* bubble_positioner,
CommandUpdater* command_updater,
ToolbarModel* toolbar_model,
Profile* profile,
Browser* browser)
- : edit_view_(new AutocompleteEditViewMac(this, bubble_positioner,
- toolbar_model, profile, command_updater, field)),
+ : edit_view_(new AutocompleteEditViewMac(this, toolbar_model, profile,
+ command_updater, field)),
command_updater_(command_updater),
field_(field),
disposition_(CURRENT_TAB),
- security_image_view_(this, profile, toolbar_model),
+ location_icon_view_(this),
+ security_label_view_(),
+ star_icon_view_(command_updater),
page_action_views_(this, profile, toolbar_model),
profile_(profile),
browser_(browser),
@@ -116,7 +120,9 @@ LocationBarViewMac::LocationBarViewMac(
}
AutocompleteTextFieldCell* cell = [field_ autocompleteTextFieldCell];
- [cell setSecurityImageView:&security_image_view_];
+ [cell setLocationIconView:&location_icon_view_];
+ [cell setSecurityLabelView:&security_label_view_];
+ [cell setStarIconView:&star_icon_view_];
[cell setPageActionViewList:&page_action_views_];
[cell setContentSettingViewsList:&content_setting_views_];
@@ -129,7 +135,9 @@ LocationBarViewMac::~LocationBarViewMac() {
// Disconnect from cell in case it outlives us.
AutocompleteTextFieldCell* cell = [field_ autocompleteTextFieldCell];
[cell setPageActionViewList:NULL];
- [cell setSecurityImageView:NULL];
+ [cell setLocationIconView:NULL];
+ [cell setSecurityLabelView:NULL];
+ [cell setStarIconView:NULL];
}
std::wstring LocationBarViewMac::GetInputString() const {
@@ -206,7 +214,7 @@ void LocationBarViewMac::SaveStateToContents(TabContents* contents) {
void LocationBarViewMac::Update(const TabContents* contents,
bool should_restore_state) {
- SetSecurityIcon(toolbar_model_->GetIcon());
+ SetIcon(edit_view_->GetIcon());
page_action_views_.RefreshViews();
RefreshContentSettingsViews();
// AutocompleteEditView restores state if the tab is non-NULL.
@@ -252,7 +260,6 @@ void LocationBarViewMac::OnChangedImpl(AutocompleteTextField* field,
const std::wstring& keyword,
const std::wstring& short_name,
const bool is_keyword_hint,
- const bool show_search_hint,
NSImage* image) {
AutocompleteTextFieldCell* cell = [field autocompleteTextFieldCell];
const CGFloat availableWidth([field availableDecorationWidth]);
@@ -298,12 +305,6 @@ void LocationBarViewMac::OnChangedImpl(AutocompleteTextField* field,
[cell setKeywordHintPrefix:prefix image:image suffix:suffix
availableWidth:availableWidth];
- } else if (show_search_hint) {
- // Show a search hint right-justified in the field if there is no
- // keyword.
- const std::wstring hint(l10n_util::GetString(IDS_OMNIBOX_EMPTY_TEXT));
- [cell setSearchHintString:base::SysWideToNSString(hint)
- availableWidth:availableWidth];
} else {
// Nothing interesting to show, plain old text field.
[cell clearKeywordAndHint];
@@ -330,7 +331,6 @@ void LocationBarViewMac::OnChanged() {
keyword,
short_name,
edit_view_->model()->is_keyword_hint(),
- edit_view_->model()->show_search_hint(),
GetTabButtonImage());
}
@@ -444,6 +444,22 @@ void LocationBarViewMac::TestPageActionPressed(size_t index) {
page_action_views_.OnMousePressed(NSZeroRect, index);
}
+void LocationBarViewMac::SetEditable(bool editable) {
+ [field_ setEditable:editable ? YES : NO];
+ star_icon_view_.SetVisible(editable);
+ UpdatePageActions();
+}
+
+bool LocationBarViewMac::IsEditable() {
+ return [field_ isEditable] ? true : false;
+}
+
+void LocationBarViewMac::SetStarred(bool starred) {
+ star_icon_view_.SetStarred(starred);
+ [field_ updateCursorAndToolTipRects];
+ [field_ resetFieldEditorFrameIfNeeded];
+}
+
NSImage* LocationBarViewMac::GetTabButtonImage() {
if (!tab_button_image_) {
SkBitmap* skiaBitmap = ResourceBundle::GetSharedInstance().
@@ -455,44 +471,37 @@ NSImage* LocationBarViewMac::GetTabButtonImage() {
return tab_button_image_;
}
-void LocationBarViewMac::SetSecurityIconLabel() {
- std::wstring info_text;
- std::wstring info_tooltip;
- ToolbarModel::InfoTextType info_text_type =
- toolbar_model_->GetInfoText(&info_text, &info_tooltip);
- if (info_text_type == ToolbarModel::INFO_EV_TEXT) {
- NSString* icon_label = base::SysWideToNSString(info_text);
- NSColor* color = [NSColor colorWithCalibratedRed:kEvTextColorRedComponent
- green:kEvTextColorGreenComponent
- blue:kEvTextColorBlueComponent
- alpha:1.0];
- security_image_view_.SetLabel(icon_label, [field_ font], color);
+void LocationBarViewMac::SetIcon(int resource_id) {
+ DCHECK(resource_id != 0);
+
+ // The icon is always visible except when there is a keyword hint.
+ if (!edit_view_->model()->keyword().empty() &&
+ !edit_view_->model()->is_keyword_hint()) {
+ location_icon_view_.SetVisible(false);
} else {
- security_image_view_.SetLabel(nil, nil, nil);
+ NSImage* image = AutocompleteEditViewMac::ImageForResource(resource_id);
+ location_icon_view_.SetImage(image);
+ location_icon_view_.SetVisible(true);
+ SetSecurityLabel();
}
+ [field_ resetFieldEditorFrameIfNeeded];
}
-void LocationBarViewMac::SetSecurityIcon(ToolbarModel::Icon icon) {
- switch (icon) {
- case ToolbarModel::LOCK_ICON:
- security_image_view_.SetImageShown(SecurityImageView::LOCK);
- security_image_view_.SetVisible(true);
- SetSecurityIconLabel();
- break;
- case ToolbarModel::WARNING_ICON:
- security_image_view_.SetImageShown(SecurityImageView::WARNING);
- security_image_view_.SetVisible(true);
- SetSecurityIconLabel();
- break;
- case ToolbarModel::NO_ICON:
- security_image_view_.SetVisible(false);
- break;
- default:
- NOTREACHED();
- security_image_view_.SetVisible(false);
- break;
+void LocationBarViewMac::SetSecurityLabel() {
+ if (toolbar_model_->GetSecurityLevel() == ToolbarModel::EV_SECURE) {
+ std::wstring security_info_text(toolbar_model_->GetEVCertName());
+ NSString* icon_label = base::SysWideToNSString(security_info_text);
+ NSColor* color =
+ [NSColor colorWithCalibratedRed:kEVSecureTextColorRedComponent
+ green:kEVSecureTextColorGreenComponent
+ blue:kEVSecureTextColorBlueComponent
+ alpha:1.0];
+ security_label_view_.SetLabel(icon_label, [field_ font], color);
+ security_label_view_.SetVisible(true);
+ } else {
+ security_label_view_.SetLabel(nil, nil, nil);
+ security_label_view_.SetVisible(false);
}
- [field_ resetFieldEditorFrameIfNeeded];
}
void LocationBarViewMac::Observe(NotificationType type,
@@ -535,8 +544,9 @@ void LocationBarViewMac::LocationBarImageView::SetImage(NSImage* image) {
image_.reset([image retain]);
}
-void LocationBarViewMac::LocationBarImageView::SetImage(SkBitmap* image) {
- SetImage(gfx::SkBitmapToNSImage(*image));
+void LocationBarViewMac::LocationBarImageView::SetIcon(int resource_id) {
+ ResourceBundle& rb = ResourceBundle::GetSharedInstance();
+ SetImage(rb.GetNSImageNamed(resource_id));
}
void LocationBarViewMac::LocationBarImageView::SetLabel(NSString* text,
@@ -564,43 +574,32 @@ void LocationBarViewMac::LocationBarImageView::SetVisible(bool visible) {
visible_ = visible;
}
-// SecurityImageView------------------------------------------------------------
+NSSize LocationBarViewMac::LocationBarImageView::GetDefaultImageSize() const {
+ return NSZeroSize;
+}
-LocationBarViewMac::SecurityImageView::SecurityImageView(
- LocationBarViewMac* owner,
- Profile* profile,
- ToolbarModel* model)
- : lock_icon_(nil),
- warning_icon_(nil),
- owner_(owner),
- profile_(profile),
- model_(model) {}
+NSSize LocationBarViewMac::LocationBarImageView::GetImageSize() const {
+ NSImage* image = GetImage();
+ if (image)
+ return [image size];
+ return GetDefaultImageSize();
+}
-LocationBarViewMac::SecurityImageView::~SecurityImageView() {}
+// LocationIconView ------------------------------------------------------------
-void LocationBarViewMac::SecurityImageView::SetImageShown(Image image) {
- switch (image) {
- case LOCK:
- if (!lock_icon_.get()) {
- ResourceBundle& rb = ResourceBundle::GetSharedInstance();
- lock_icon_.reset([rb.GetNSImageNamed(IDR_LOCK) retain]);
- }
- SetImage(lock_icon_);
- break;
- case WARNING:
- if (!warning_icon_.get()) {
- ResourceBundle& rb = ResourceBundle::GetSharedInstance();
- warning_icon_.reset([rb.GetNSImageNamed(IDR_WARNING) retain]);
- }
- SetImage(warning_icon_);
- break;
- default:
- NOTREACHED();
- break;
- }
+LocationBarViewMac::LocationIconView::LocationIconView(
+ LocationBarViewMac* owner)
+ : owner_(owner) {
}
-void LocationBarViewMac::SecurityImageView::OnMousePressed(NSRect bounds) {
+LocationBarViewMac::LocationIconView::~LocationIconView() {}
+
+void LocationBarViewMac::LocationIconView::OnMousePressed(NSRect bounds) {
+ // Do not show page info if the user has been editing the location
+ // bar, or the location bar is at the NTP.
+ if (owner_->location_entry()->IsEditingOrEmpty())
+ return;
+
TabContents* tab = owner_->GetTabContents();
NavigationEntry* nav_entry = tab->controller().GetActiveEntry();
if (!nav_entry) {
@@ -610,6 +609,57 @@ void LocationBarViewMac::SecurityImageView::OnMousePressed(NSRect bounds) {
tab->ShowPageInfo(nav_entry->url(), nav_entry->ssl(), true);
}
+bool LocationBarViewMac::LocationIconView::IsDraggable() {
+ // Do not drag if the user has been editing the location bar, or the
+ // location bar is at the NTP.
+ if (owner_->location_entry()->IsEditingOrEmpty())
+ return false;
+
+ return true;
+}
+
+NSPasteboard* LocationBarViewMac::LocationIconView::GetDragPasteboard() {
+ TabContents* tab = owner_->GetTabContents();
+ DCHECK(tab);
+
+ NSString* url = base::SysUTF8ToNSString(tab->GetURL().spec());
+ NSString* title = base::SysUTF16ToNSString(tab->GetTitle());
+
+ NSPasteboard* pboard = [NSPasteboard pasteboardWithName:NSDragPboard];
+ [pboard declareURLPasteboardWithAdditionalTypes:[NSArray array]
+ owner:nil];
+ [pboard setDataForURL:url title:title];
+ return pboard;
+}
+
+// StarIconView-----------------------------------------------------------------
+
+LocationBarViewMac::StarIconView::StarIconView(CommandUpdater* command_updater)
+ : command_updater_(command_updater) {
+ SetVisible(true);
+ SetStarred(false);
+}
+
+void LocationBarViewMac::StarIconView::SetStarred(bool starred) {
+ if (starred) {
+ SetImage(AutocompleteEditViewMac::ImageForResource(IDR_OMNIBOX_STAR_LIT));
+ tooltip_.reset(
+ [l10n_util::GetNSStringWithFixup(IDS_TOOLTIP_STARRED) retain]);
+ } else {
+ SetImage(AutocompleteEditViewMac::ImageForResource(IDR_OMNIBOX_STAR));
+ tooltip_.reset(
+ [l10n_util::GetNSStringWithFixup(IDS_TOOLTIP_STAR) retain]);
+ }
+}
+
+void LocationBarViewMac::StarIconView::OnMousePressed(NSRect bounds) {
+ command_updater_->ExecuteCommand(IDC_BOOKMARK_PAGE);
+}
+
+const NSString* LocationBarViewMac::StarIconView::GetToolTip() {
+ return tooltip_.get();
+}
+
// PageActionImageView----------------------------------------------------------
LocationBarViewMac::PageActionImageView::PageActionImageView(
@@ -647,14 +697,9 @@ LocationBarViewMac::PageActionImageView::PageActionImageView(
LocationBarViewMac::PageActionImageView::~PageActionImageView() {
}
-NSSize LocationBarViewMac::PageActionImageView::GetPreferredImageSize() {
- NSImage* image = GetImage();
- if (image) {
- return [image size];
- } else {
- return NSMakeSize(Extension::kPageActionIconMaxSize,
- Extension::kPageActionIconMaxSize);
- }
+NSSize LocationBarViewMac::PageActionImageView::GetDefaultImageSize() const {
+ return NSMakeSize(Extension::kPageActionIconMaxSize,
+ Extension::kPageActionIconMaxSize);
}
// Overridden from LocationBarImageView. Either notify listeners or show a
@@ -868,10 +913,9 @@ void LocationBarViewMac::ContentSettingImageView::UpdateFromTabContents(
const TabContents* tab_contents) {
content_setting_image_model_->UpdateFromTabContents(tab_contents);
if (content_setting_image_model_->is_visible()) {
- ResourceBundle& rb = ResourceBundle::GetSharedInstance();
// TODO(thakis): We should use pdfs for these icons on OSX.
// http://crbug.com/35847
- SetImage(rb.GetNSImageNamed(content_setting_image_model_->get_icon()));
+ SetIcon(content_setting_image_model_->get_icon());
SetToolTip(base::SysUTF8ToNSString(
content_setting_image_model_->get_tooltip()));
SetVisible(true);
@@ -895,6 +939,11 @@ void LocationBarViewMac::PageActionViewList::DeleteAll() {
}
void LocationBarViewMac::PageActionViewList::RefreshViews() {
+ if (!owner_->IsEditable()) {
+ DeleteAll();
+ return;
+ }
+
std::vector<ExtensionAction*> page_actions;
ExtensionsService* service = profile_->GetExtensionsService();
if (!service)
diff --git a/chrome/browser/cocoa/location_bar_view_mac_unittest.mm b/chrome/browser/cocoa/location_bar_view_mac_unittest.mm
index aec948d..ecb2a7b 100644
--- a/chrome/browser/cocoa/location_bar_view_mac_unittest.mm
+++ b/chrome/browser/cocoa/location_bar_view_mac_unittest.mm
@@ -81,7 +81,6 @@ TEST_F(LocationBarViewMacTest, OnChangedImpl) {
NSImage* image = [NSImage imageNamed:@"NSApplicationIcon"];
const std::wstring kKeyword(L"Google");
- const NSString* kSearchHint = @"Type to search";
const NSString* kKeywordPrefix = @"Press ";
const NSString* kKeywordSuffix = @" to search Google";
const NSString* kKeywordString = @"Search Google:";
@@ -90,39 +89,20 @@ TEST_F(LocationBarViewMacTest, OnChangedImpl) {
[NSString stringWithFormat:@"Search Go%C:", 0x2026];
// With no special hints requested, none set.
- LocationBarViewMac::OnChangedImpl(
- field_, std::wstring(), std::wstring(), false, false, image);
+ LocationBarViewMac::OnChangedImpl(field_, std::wstring(), std::wstring(), false, image);
EXPECT_FALSE([cell keywordString]);
EXPECT_FALSE([cell hintString]);
- // Request only a search hint.
- LocationBarViewMac::OnChangedImpl(
- field_, std::wstring(), std::wstring(), false, true, image);
- EXPECT_FALSE([cell keywordString]);
- EXPECT_TRUE([[[cell hintString] string] isEqualToString:kSearchHint]);
-
- // Request a keyword hint, same results whether |search_hint|
- // parameter is true or false.
- LocationBarViewMac::OnChangedImpl(
- field_, kKeyword, kKeyword, true, true, image);
- EXPECT_FALSE([cell keywordString]);
- EXPECT_TRUE([[[cell hintString] string] hasPrefix:kKeywordPrefix]);
- EXPECT_TRUE([[[cell hintString] string] hasSuffix:kKeywordSuffix]);
- LocationBarViewMac::OnChangedImpl(
- field_, kKeyword, kKeyword, true, false, image);
+ // Request a keyword hint.
+ LocationBarViewMac::OnChangedImpl(field_, kKeyword, kKeyword, true, image);
EXPECT_FALSE([cell keywordString]);
EXPECT_TRUE([[[cell hintString] string] hasPrefix:kKeywordPrefix]);
EXPECT_TRUE([[[cell hintString] string] hasSuffix:kKeywordSuffix]);
- // Request keyword-search mode, same results whether |search_hint|
- // parameter is true or false.
+ // Request keyword-search mode.
LocationBarViewMac::OnChangedImpl(
- field_, kKeyword, kKeyword, false, true, image);
- EXPECT_TRUE([[[cell keywordString] string] isEqualToString:kKeywordString]);
- EXPECT_FALSE([cell hintString]);
- LocationBarViewMac::OnChangedImpl(
- field_, kKeyword, kKeyword, false, false, image);
- EXPECT_TRUE([[[cell keywordString] string] isEqualToString:kKeywordString]);
+ field_, kKeyword, kKeyword, false, image);
+ EXPECT_TRUE([[[cell keywordString] string] hasSuffix:kKeywordString]);
EXPECT_FALSE([cell hintString]);
// Check that a partial keyword-search string is passed down in case
@@ -132,14 +112,13 @@ TEST_F(LocationBarViewMacTest, OnChangedImpl) {
NSRect frame([field_ frame]);
frame.size.width = 10.0;
[field_ setFrame:frame];
- LocationBarViewMac::OnChangedImpl(
- field_, kKeyword, kKeyword, false, true, image);
+ LocationBarViewMac::OnChangedImpl(field_, kKeyword, kKeyword, false, image);
EXPECT_TRUE([[[cell keywordString] string] isEqualToString:kPartialString]);
EXPECT_FALSE([cell hintString]);
// Transition back to baseline.
LocationBarViewMac::OnChangedImpl(
- field_, std::wstring(), std::wstring(), false, false, image);
+ field_, std::wstring(), std::wstring(), false, image);
EXPECT_FALSE([cell keywordString]);
EXPECT_FALSE([cell hintString]);
}
diff --git a/chrome/browser/cocoa/status_bubble_mac_unittest.mm b/chrome/browser/cocoa/status_bubble_mac_unittest.mm
index 3dd628e..6f4dab4 100644
--- a/chrome/browser/cocoa/status_bubble_mac_unittest.mm
+++ b/chrome/browser/cocoa/status_bubble_mac_unittest.mm
@@ -141,7 +141,7 @@ TEST_F(StatusBubbleMacTest, SetURL) {
EXPECT_TRUE([GetURLText() isEqualToString:@"foopy://"]);
bubble_->SetURL(GURL("http://www.cnn.com"), L"");
EXPECT_TRUE(IsVisible());
- EXPECT_TRUE([GetURLText() isEqualToString:@"http://www.cnn.com/"]);
+ EXPECT_TRUE([GetURLText() isEqualToString:@"www.cnn.com/"]);
}
// Test hiding bubble that's already hidden.
@@ -162,7 +162,7 @@ TEST_F(StatusBubbleMacTest, SetStatusAndURL) {
EXPECT_TRUE([GetBubbleViewText() isEqualToString:@"Status"]);
bubble_->SetURL(GURL("http://www.nytimes.com/"), L"");
EXPECT_TRUE(IsVisible());
- EXPECT_TRUE([GetBubbleViewText() isEqualToString:@"http://www.nytimes.com/"]);
+ EXPECT_TRUE([GetBubbleViewText() isEqualToString:@"www.nytimes.com/"]);
bubble_->SetURL(GURL(), L"");
EXPECT_TRUE(IsVisible());
EXPECT_TRUE([GetBubbleViewText() isEqualToString:@"Status"]);
@@ -170,13 +170,13 @@ TEST_F(StatusBubbleMacTest, SetStatusAndURL) {
EXPECT_FALSE(IsVisible());
bubble_->SetURL(GURL("http://www.nytimes.com/"), L"");
EXPECT_TRUE(IsVisible());
- EXPECT_TRUE([GetBubbleViewText() isEqualToString:@"http://www.nytimes.com/"]);
+ EXPECT_TRUE([GetBubbleViewText() isEqualToString:@"www.nytimes.com/"]);
bubble_->SetStatus(L"Status");
EXPECT_TRUE(IsVisible());
EXPECT_TRUE([GetBubbleViewText() isEqualToString:@"Status"]);
bubble_->SetStatus(L"");
EXPECT_TRUE(IsVisible());
- EXPECT_TRUE([GetBubbleViewText() isEqualToString:@"http://www.nytimes.com/"]);
+ EXPECT_TRUE([GetBubbleViewText() isEqualToString:@"www.nytimes.com/"]);
bubble_->SetURL(GURL(), L"");
EXPECT_FALSE(IsVisible());
}
diff --git a/chrome/browser/cocoa/tab_strip_controller_unittest.mm b/chrome/browser/cocoa/tab_strip_controller_unittest.mm
index 0967ae4..82cea8e 100644
--- a/chrome/browser/cocoa/tab_strip_controller_unittest.mm
+++ b/chrome/browser/cocoa/tab_strip_controller_unittest.mm
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 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.
diff --git a/chrome/browser/cocoa/toolbar_controller.h b/chrome/browser/cocoa/toolbar_controller.h
index 0fdd8c4..1f277c1 100644
--- a/chrome/browser/cocoa/toolbar_controller.h
+++ b/chrome/browser/cocoa/toolbar_controller.h
@@ -22,7 +22,6 @@ class AppMenuModel;
@class BackForwardMenuController;
class Browser;
@class BrowserActionsController;
-class BubblePositioner;
class CommandUpdater;
@class DelayedMenuButton;
class LocationBar;
@@ -70,8 +69,6 @@ class ToolbarModel;
// Used for monitoring the optional toolbar button prefs.
scoped_ptr<ToolbarControllerInternal::PrefObserverBridge> prefObserver_;
- // Used to position the omnibox bubble.
- scoped_ptr<BubblePositioner> bubblePositioner_;
BooleanPrefMember showHomeButton_;
BooleanPrefMember showPageOptionButtons_;
BOOL hasToolbar_; // If NO, we may have only the location bar.
@@ -99,7 +96,6 @@ class ToolbarModel;
IBOutlet DelayedMenuButton* forwardButton_;
IBOutlet NSButton* reloadButton_;
IBOutlet NSButton* homeButton_;
- IBOutlet NSButton* starButton_;
IBOutlet NSButton* goButton_;
IBOutlet MenuButton* pageButton_;
IBOutlet MenuButton* wrenchButton_;
@@ -147,9 +143,10 @@ class ToolbarModel;
// ignored. This changes the behavior of other methods, like |-view|.
- (void)setHasToolbar:(BOOL)toolbar hasLocationBar:(BOOL)locBar;
-// The bookmark bubble (when you click the star) needs to know where to go.
-// Somewhere near the star button seems like a good start.
-- (NSRect)starButtonInWindowCoordinates;
+// The bookmark bubble (when you click the star or hit Command-d)
+// needs to know where to go. Somewhere near the star icon seems like
+// a good start.
+- (NSRect)starIconInWindowCoordinates;
// Returns the desired toolbar height for the given compression factor.
- (CGFloat)desiredHeightForCompression:(CGFloat)compressByHeight;
@@ -171,7 +168,6 @@ class ToolbarModel;
- (NSArray*)toolbarViews;
- (void)showOptionalHomeButton;
- (void)showOptionalPageWrenchButtons;
-- (gfx::Rect)locationStackBounds;
// Return a hover button for the current event.
- (NSButton*)hoverButtonForEvent:(NSEvent*)theEvent;
@end
diff --git a/chrome/browser/cocoa/toolbar_controller.mm b/chrome/browser/cocoa/toolbar_controller.mm
index 1412fc1..a9c4a33 100644
--- a/chrome/browser/cocoa/toolbar_controller.mm
+++ b/chrome/browser/cocoa/toolbar_controller.mm
@@ -15,7 +15,6 @@
#include "chrome/browser/autocomplete/autocomplete_edit_view.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_window.h"
-#include "chrome/browser/bubble_positioner.h"
#import "chrome/browser/cocoa/autocomplete_text_field.h"
#import "chrome/browser/cocoa/autocomplete_text_field_editor.h"
#import "chrome/browser/cocoa/back_forward_menu_controller.h"
@@ -51,8 +50,6 @@ NSString* const kBackButtonImageName = @"back_Template.pdf";
NSString* const kForwardButtonImageName = @"forward_Template.pdf";
NSString* const kReloadButtonImageName = @"reload_Template.pdf";
NSString* const kHomeButtonImageName = @"home_Template.pdf";
-NSString* const kStarButtonImageName = @"star_Template.pdf";
-NSString* const kStarButtonFillingImageName = @"starred.pdf";
NSString* const kGoButtonGoImageName = @"go_Template.pdf";
NSString* const kGoButtonStopImageName = @"stop_Template.pdf";
NSString* const kPageButtonImageName = @"menu_page_Template.pdf";
@@ -87,26 +84,6 @@ const CGFloat kAnimationDuration = 0.2;
- (void)adjustLocationAndGoPositionsBy:(CGFloat)dX animate:(BOOL)animate;
@end
-namespace {
-
-// A C++ class used to correctly position the omnibox.
-class BubblePositionerMac : public BubblePositioner {
- public:
- BubblePositionerMac(ToolbarController* controller)
- : controller_(controller) { }
- virtual ~BubblePositionerMac() { }
-
- // BubblePositioner:
- virtual gfx::Rect GetLocationStackBounds() const {
- return [controller_ locationStackBounds];
- }
-
- private:
- ToolbarController* controller_; // weak, owns us
-};
-
-} // namespace
-
namespace ToolbarControllerInternal {
// A C++ delegate that handles enabling/disabling menu items and handling when
@@ -225,7 +202,6 @@ class PrefObserverBridge : public NotificationObserver {
[forwardButton_ setImage:nsimage_cache::ImageNamed(kForwardButtonImageName)];
[reloadButton_ setImage:nsimage_cache::ImageNamed(kReloadButtonImageName)];
[homeButton_ setImage:nsimage_cache::ImageNamed(kHomeButtonImageName)];
- [starButton_ setImage:nsimage_cache::ImageNamed(kStarButtonImageName)];
[goButton_ setImage:nsimage_cache::ImageNamed(kGoButtonGoImageName)];
[pageButton_ setImage:nsimage_cache::ImageNamed(kPageButtonImageName)];
[wrenchButton_ setImage:nsimage_cache::ImageNamed(kWrenchButtonImageName)];
@@ -234,9 +210,7 @@ class PrefObserverBridge : public NotificationObserver {
[wrenchButton_ setShowsBorderOnlyWhileMouseInside:YES];
[self initCommandStatus:commands_];
- bubblePositioner_.reset(new BubblePositionerMac(self));
locationBarView_.reset(new LocationBarViewMac(locationBar_,
- bubblePositioner_.get(),
commands_, toolbarModel_,
profile_, browser_));
[locationBar_ setFont:[NSFont systemFontOfSize:[NSFont systemFontSize]]];
@@ -312,10 +286,6 @@ class PrefObserverBridge : public NotificationObserver {
[[homeButton_ cell]
accessibilitySetOverrideValue:description
forAttribute:NSAccessibilityDescriptionAttribute];
- description = l10n_util::GetNSStringWithFixup(IDS_ACCNAME_STAR);
- [[starButton_ cell]
- accessibilitySetOverrideValue:description
- forAttribute:NSAccessibilityDescriptionAttribute];
description = l10n_util::GetNSStringWithFixup(IDS_ACCNAME_LOCATION);
[[locationBar_ cell]
accessibilitySetOverrideValue:description
@@ -393,9 +363,6 @@ class PrefObserverBridge : public NotificationObserver {
case IDC_HOME:
button = homeButton_;
break;
- case IDC_BOOKMARK_PAGE:
- button = starButton_;
- break;
}
[button setEnabled:enabled];
}
@@ -408,8 +375,6 @@ class PrefObserverBridge : public NotificationObserver {
setEnabled:commands->IsCommandEnabled(IDC_FORWARD) ? YES : NO];
[reloadButton_ setEnabled:commands->IsCommandEnabled(IDC_RELOAD) ? YES : NO];
[homeButton_ setEnabled:commands->IsCommandEnabled(IDC_HOME) ? YES : NO];
- [starButton_
- setEnabled:commands->IsCommandEnabled(IDC_BOOKMARK_PAGE) ? YES : NO];
}
- (void)updateToolbarWithContents:(TabContents*)tab
@@ -424,23 +389,7 @@ class PrefObserverBridge : public NotificationObserver {
}
- (void)setStarredState:(BOOL)isStarred {
- NSImage* starImage = nil;
- NSString* toolTip;
- if (isStarred) {
- starImage = nsimage_cache::ImageNamed(kStarButtonFillingImageName);
- // Cache the string since we'll need it a lot
- static NSString* starredToolTip =
- [l10n_util::GetNSStringWithFixup(IDS_TOOLTIP_STARRED) retain];
- toolTip = starredToolTip;
- } else {
- // Cache the string since we'll need it a lot
- static NSString* starToolTip =
- [l10n_util::GetNSStringWithFixup(IDS_TOOLTIP_STAR) retain];
- toolTip = starToolTip;
- }
-
- [(GradientButtonCell*)[starButton_ cell] setUnderlayImage:starImage];
- [starButton_ setToolTip:toolTip];
+ locationBarView_->SetStarred(isStarred ? true : false);
}
- (void)setIsLoading:(BOOL)isLoading {
@@ -469,7 +418,7 @@ class PrefObserverBridge : public NotificationObserver {
// Make location bar not editable when in a pop-up.
// TODO(viettrungluu): is this right (all the time)?
- [locationBar_ setEditable:toolbar];
+ locationBarView_->SetEditable(toolbar ? true : false);
}
- (NSView*)view {
@@ -507,7 +456,7 @@ class PrefObserverBridge : public NotificationObserver {
// Returns an array of views in the order of the outlets above.
- (NSArray*)toolbarViews {
return [NSArray arrayWithObjects:backButton_, forwardButton_, reloadButton_,
- homeButton_, starButton_, goButton_, pageButton_, wrenchButton_,
+ homeButton_, goButton_, pageButton_, wrenchButton_,
locationBar_, browserActionsContainerView_, nil];
}
@@ -520,14 +469,16 @@ class PrefObserverBridge : public NotificationObserver {
return frame;
}
-// Computes the padding between the buttons that should have a separation from
-// the positions in the nib. Since the forward and reload buttons are always
-// visible, we use those buttons as the canonical spacing.
+// Computes the padding between the buttons that should have a
+// separation from the positions in the nib. |homeButton_| is right
+// of |forwardButton_| unless it has been hidden, in which case
+// |reloadButton_| is in that spot.
- (CGFloat)interButtonSpacing {
- NSRect forwardFrame = [forwardButton_ frame];
- NSRect reloadFrame = [reloadButton_ frame];
- DCHECK(NSMinX(reloadFrame) > NSMaxX(forwardFrame));
- return NSMinX(reloadFrame) - NSMaxX(forwardFrame);
+ const NSRect forwardFrame = [forwardButton_ frame];
+ NSButton* nextButton = [homeButton_ isHidden] ? reloadButton_ : homeButton_;
+ const NSRect nextButtonFrame = [nextButton frame];
+ DCHECK_GT(NSMinX(nextButtonFrame), NSMaxX(forwardFrame));
+ return NSMinX(nextButtonFrame) - NSMaxX(forwardFrame);
}
// Show or hide the home button based on the pref.
@@ -546,7 +497,7 @@ class PrefObserverBridge : public NotificationObserver {
if (hide)
moveX *= -1; // Reverse the direction of the move.
- [starButton_ setFrame:NSOffsetRect([starButton_ frame], moveX, 0)];
+ [reloadButton_ setFrame:NSOffsetRect([reloadButton_ frame], moveX, 0)];
[locationBar_ setFrame:[self adjustRect:[locationBar_ frame]
byAmount:moveX]];
[homeButton_ setHidden:hide];
@@ -769,8 +720,8 @@ class PrefObserverBridge : public NotificationObserver {
[NSAnimationContext endGrouping];
}
-- (NSRect)starButtonInWindowCoordinates {
- return [starButton_ convertRect:[starButton_ bounds] toView:nil];
+- (NSRect)starIconInWindowCoordinates {
+ return [locationBar_ convertRect:[locationBar_ starIconFrame] toView:nil];
}
- (CGFloat)desiredHeightForCompression:(CGFloat)compressByHeight {
@@ -845,31 +796,6 @@ class PrefObserverBridge : public NotificationObserver {
}
-- (gfx::Rect)locationStackBounds {
- // The number of pixels from the left or right edges of the location stack to
- // "just inside the visible borders". When the omnibox bubble contents are
- // aligned with this, the visible borders tacked on to the outsides will line
- // up with the visible borders on the location stack.
- const int kLocationStackEdgeWidth = 2;
-
- const NSRect locationFrame = [locationBar_ frame];
-
- // Expand to include star and go buttons. Including the widths
- // rather that calculating from their current placement because this
- // method can be called while the resize is still rearranging the
- // views involved.
- const CGFloat minX = NSMinX(locationFrame) - NSWidth([starButton_ frame]);
- const CGFloat maxX = NSMaxX(locationFrame) + NSWidth([goButton_ frame]);
-
- NSRect r = NSMakeRect(minX, NSMinY(locationFrame), maxX - minX,
- NSHeight(locationFrame));
- gfx::Rect stack_bounds(
- NSRectToCGRect([[self view] convertRect:r toView:nil]));
- // Inset the bounds to just inside the visible edges (see comment above).
- stack_bounds.Inset(kLocationStackEdgeWidth, 0);
- return stack_bounds;
-}
-
// (URLDropTargetController protocol)
- (void)dropURLs:(NSArray*)urls inView:(NSView*)view at:(NSPoint)point {
// TODO(viettrungluu): This code is more or less copied from the code in
diff --git a/chrome/browser/cocoa/toolbar_controller_unittest.mm b/chrome/browser/cocoa/toolbar_controller_unittest.mm
index 7c718c4..dcea565 100644
--- a/chrome/browser/cocoa/toolbar_controller_unittest.mm
+++ b/chrome/browser/cocoa/toolbar_controller_unittest.mm
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 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.
@@ -43,7 +43,7 @@ class ToolbarControllerTest : public CocoaTest {
// Indexes that match the ordering returned by the private ToolbarController
// |-toolbarViews| method.
enum {
- kBackIndex, kForwardIndex, kReloadIndex, kHomeIndex, kStarIndex, kGoIndex,
+ kBackIndex, kForwardIndex, kReloadIndex, kHomeIndex, kGoIndex,
kPageIndex, kWrenchIndex, kLocationIndex,
kBrowserActionContainerViewIndex
};
@@ -78,8 +78,6 @@ class ToolbarControllerTest : public CocoaTest {
[[views objectAtIndex:kReloadIndex] isEnabled] ? true : false);
EXPECT_EQ(updater->IsCommandEnabled(IDC_HOME),
[[views objectAtIndex:kHomeIndex] isEnabled] ? true : false);
- EXPECT_EQ(updater->IsCommandEnabled(IDC_BOOKMARK_PAGE),
- [[views objectAtIndex:kStarIndex] isEnabled] ? true : false);
}
BrowserTestHelper helper_;
@@ -160,16 +158,16 @@ TEST_F(ToolbarControllerTest, ToggleHome) {
NSView* homeButton = [[bar_ toolbarViews] objectAtIndex:kHomeIndex];
EXPECT_EQ(showHome, ![homeButton isHidden]);
- NSView* starButton = [[bar_ toolbarViews] objectAtIndex:kStarIndex];
+ NSView* reloadButton = [[bar_ toolbarViews] objectAtIndex:kReloadIndex];
NSView* locationBar = [[bar_ toolbarViews] objectAtIndex:kLocationIndex];
- NSRect originalStarFrame = [starButton frame];
+ NSRect originalReloadFrame = [reloadButton frame];
NSRect originalLocationBarFrame = [locationBar frame];
// Toggle the pref and make sure the button changed state and the other
// views moved.
prefs->SetBoolean(prefs::kShowHomeButton, !showHome);
EXPECT_EQ(showHome, [homeButton isHidden]);
- EXPECT_NE(NSMinX(originalStarFrame), NSMinX([starButton frame]));
+ EXPECT_NE(NSMinX(originalReloadFrame), NSMinX([reloadButton frame]));
EXPECT_NE(NSMinX(originalLocationBarFrame), NSMinX([locationBar frame]));
EXPECT_NE(NSWidth(originalLocationBarFrame), NSWidth([locationBar frame]));
}
@@ -220,32 +218,14 @@ TEST_F(ToolbarControllerTest, DontToggleWhenNoToolbar) {
EXPECT_TRUE(NSEqualRects(locationBarFrame, newLocationBarFrame));
}
-TEST_F(ToolbarControllerTest, StarButtonInWindowCoordinates) {
- NSRect star = [bar_ starButtonInWindowCoordinates];
+TEST_F(ToolbarControllerTest, StarIconInWindowCoordinates) {
+ NSRect star = [bar_ starIconInWindowCoordinates];
NSRect all = [[[bar_ view] window] frame];
// Make sure the star is completely inside the window rect
EXPECT_TRUE(NSContainsRect(all, star));
}
-TEST_F(ToolbarControllerTest, BubblePosition) {
- NSView* locationBar = [[bar_ toolbarViews] objectAtIndex:kLocationIndex];
-
- // The window frame (in window base coordinates).
- NSRect all = [[[bar_ view] window] frame];
- // The frame of the location bar in window base coordinates.
- NSRect locationFrame =
- [locationBar convertRect:[locationBar bounds] toView:nil];
- // The frame of the location stack in window base coordinates. The horizontal
- // coordinates here are used for the omnibox dropdown.
- gfx::Rect locationStackFrame = [bar_ locationStackBounds];
-
- // Make sure the location stack starts to the left of and ends to the right of
- // the location bar.
- EXPECT_LT(locationStackFrame.x(), NSMinX(locationFrame));
- EXPECT_GT(locationStackFrame.right(), NSMaxX(locationFrame));
-}
-
TEST_F(ToolbarControllerTest, HoverButtonForEvent) {
scoped_nsobject<HitView> view([[HitView alloc]
initWithFrame:NSMakeRect(0,0,100,100)]);