summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsail@chromium.org <sail@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-07 01:55:12 +0000
committersail@chromium.org <sail@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-07 01:55:12 +0000
commit51152d6d9faa5207b5c8a1a2b9dde59fc5e4cdc2 (patch)
treec616d1b5abe92e36e603275f6d26ae7611e4b24c
parentf7c0266e3999241b233abc2ce3efcc74f6ca305b (diff)
downloadchromium_src-51152d6d9faa5207b5c8a1a2b9dde59fc5e4cdc2.zip
chromium_src-51152d6d9faa5207b5c8a1a2b9dde59fc5e4cdc2.tar.gz
chromium_src-51152d6d9faa5207b5c8a1a2b9dde59fc5e4cdc2.tar.bz2
Cocoa: Align avatar bubble with edge of anchor control
With this change the avatar bubble now aligns to the right edge of the user name in the NTP. Note, I'd like to something similar when we show the avatar bubble from the browser frame. I'll do that in separate CL though since it's a bigger change that involves moving the position of the arrow. BUG=98884 TEST=Clicked on the login name in the NTP and verified that the right edge of the avatar bubble was aligned with the right edge of the login name. Ran unit tests and verified that they passed. Review URL: http://codereview.chromium.org/8437102 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@108827 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/ui/cocoa/base_bubble_controller.mm34
-rw-r--r--chrome/browser/ui/cocoa/base_bubble_controller_unittest.mm112
-rw-r--r--chrome/browser/ui/cocoa/browser_window_cocoa.mm2
-rw-r--r--chrome/browser/ui/cocoa/info_bubble_view.h9
-rw-r--r--chrome/browser/ui/cocoa/info_bubble_view.mm2
-rw-r--r--chrome/chrome_tests.gypi1
6 files changed, 153 insertions, 7 deletions
diff --git a/chrome/browser/ui/cocoa/base_bubble_controller.mm b/chrome/browser/ui/cocoa/base_bubble_controller.mm
index 0a7b509..986364e 100644
--- a/chrome/browser/ui/cocoa/base_bubble_controller.mm
+++ b/chrome/browser/ui/cocoa/base_bubble_controller.mm
@@ -195,14 +195,34 @@ class Bridge : public content::NotificationObserver {
- (void)updateOriginFromAnchor {
NSWindow* window = [self window];
NSPoint origin = anchor_;
- NSSize offsets = NSMakeSize(info_bubble::kBubbleArrowXOffset +
- info_bubble::kBubbleArrowWidth / 2.0, 0);
- offsets = [[parentWindow_ contentView] convertSize:offsets toView:nil];
- if ([bubble_ arrowLocation] == info_bubble::kTopRight) {
- origin.x -= NSWidth([window frame]) - offsets.width;
- } else {
- origin.x -= offsets.width;
+
+ switch ([bubble_ alignment]) {
+ case info_bubble::kAlignArrowToAnchor: {
+ NSSize offsets = NSMakeSize(info_bubble::kBubbleArrowXOffset +
+ info_bubble::kBubbleArrowWidth / 2.0, 0);
+ offsets = [[parentWindow_ contentView] convertSize:offsets toView:nil];
+ if ([bubble_ arrowLocation] == info_bubble::kTopRight) {
+ origin.x -= NSWidth([window frame]) - offsets.width;
+ } else {
+ origin.x -= offsets.width;
+ }
+ break;
+ }
+
+ case info_bubble::kAlignEdgeToAnchorEdge:
+ // If the arrow is to the right then move the origin so that the right
+ // edge aligns with the anchor. If the arrow is to the left then there's
+ // nothing to do becaues the left edge is already aligned with the left
+ // edge of the anchor.
+ if ([bubble_ arrowLocation] == info_bubble::kTopRight) {
+ origin.x -= NSWidth([window frame]);
+ }
+ break;
+
+ default:
+ NOTREACHED();
}
+
origin.y -= NSHeight([window frame]);
[window setFrameOrigin:origin];
}
diff --git a/chrome/browser/ui/cocoa/base_bubble_controller_unittest.mm b/chrome/browser/ui/cocoa/base_bubble_controller_unittest.mm
new file mode 100644
index 0000000..907c27a
--- /dev/null
+++ b/chrome/browser/ui/cocoa/base_bubble_controller_unittest.mm
@@ -0,0 +1,112 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "chrome/browser/ui/cocoa/base_bubble_controller.h"
+
+#include "base/memory/scoped_nsobject.h"
+#include "chrome/browser/ui/cocoa/cocoa_test_helper.h"
+#include "chrome/browser/ui/cocoa/info_bubble_view.h"
+
+namespace {
+const CGFloat kBubbleWindowWidth = 100;
+const CGFloat kBubbleWindowHeight = 50;
+const CGFloat kAnchorPointX = 400;
+const CGFloat kAnchorPointY = 300;
+} // namespace
+
+class BaseBubbleControllerTest : public CocoaTest {
+ public:
+ virtual void SetUp() OVERRIDE {
+ bubbleWindow_.reset([[NSWindow alloc]
+ initWithContentRect:NSMakeRect(0, 0, kBubbleWindowWidth,
+ kBubbleWindowHeight)
+ styleMask:NSBorderlessWindowMask
+ backing:NSBackingStoreBuffered
+ defer:YES]);
+
+ // The bubble controller will release itself when the window closes.
+ controller_ = [[BaseBubbleController alloc]
+ initWithWindow:bubbleWindow_.get()
+ parentWindow:test_window()
+ anchoredAt:NSMakePoint(kAnchorPointX, kAnchorPointY)];
+ EXPECT_TRUE([controller_ bubble]);
+ }
+
+ virtual void TearDown() OVERRIDE {
+ // Close our windows.
+ [controller_ close];
+ bubbleWindow_.reset(NULL);
+ CocoaTest::TearDown();
+ }
+
+ public:
+ scoped_nsobject<NSWindow> bubbleWindow_;
+ BaseBubbleController* controller_;
+};
+
+// Test that kAlignEdgeToAnchorEdge and a left bubble arrow correctly aligns the
+// left edge of the buble to the anchor point.
+TEST_F(BaseBubbleControllerTest, LeftAlign) {
+ [[controller_ bubble] setArrowLocation:info_bubble::kTopLeft];
+ [[controller_ bubble] setAlignment:info_bubble::kAlignEdgeToAnchorEdge];
+ [controller_ showWindow:nil];
+
+ NSRect frame = [[controller_ window] frame];
+ // Make sure the bubble size hasn't changed.
+ EXPECT_EQ(frame.size.width, kBubbleWindowWidth);
+ EXPECT_EQ(frame.size.height, kBubbleWindowHeight);
+ // Make sure the bubble is left aligned.
+ EXPECT_EQ(NSMinX(frame), kAnchorPointX);
+ EXPECT_GE(NSMaxY(frame), kAnchorPointY);
+}
+
+// Test that kAlignEdgeToAnchorEdge and a right bubble arrow correctly aligns
+// the right edge of the buble to the anchor point.
+TEST_F(BaseBubbleControllerTest, RightAlign) {
+ [[controller_ bubble] setArrowLocation:info_bubble::kTopRight];
+ [[controller_ bubble] setAlignment:info_bubble::kAlignEdgeToAnchorEdge];
+ [controller_ showWindow:nil];
+
+ NSRect frame = [[controller_ window] frame];
+ // Make sure the bubble size hasn't changed.
+ EXPECT_EQ(frame.size.width, kBubbleWindowWidth);
+ EXPECT_EQ(frame.size.height, kBubbleWindowHeight);
+ // Make sure the bubble is left aligned.
+ EXPECT_EQ(NSMaxX(frame), kAnchorPointX);
+ EXPECT_GE(NSMaxY(frame), kAnchorPointY);
+}
+
+// Test that kAlignArrowToAnchor and a left bubble arrow correctly aligns
+// the bubble arrow to the anchor point.
+TEST_F(BaseBubbleControllerTest, AnchorAlignLeftArrow) {
+ [[controller_ bubble] setArrowLocation:info_bubble::kTopLeft];
+ [[controller_ bubble] setAlignment:info_bubble::kAlignArrowToAnchor];
+ [controller_ showWindow:nil];
+
+ NSRect frame = [[controller_ window] frame];
+ // Make sure the bubble size hasn't changed.
+ EXPECT_EQ(frame.size.width, kBubbleWindowWidth);
+ EXPECT_EQ(frame.size.height, kBubbleWindowHeight);
+ // Make sure the bubble arrow points to the anchor.
+ EXPECT_EQ(NSMinX(frame) + info_bubble::kBubbleArrowXOffset +
+ roundf(info_bubble::kBubbleArrowWidth / 2.0), kAnchorPointX);
+ EXPECT_GE(NSMaxY(frame), kAnchorPointY);
+}
+
+// Test that kAlignArrowToAnchor and a right bubble arrow correctly aligns
+// the bubble arrow to the anchor point.
+TEST_F(BaseBubbleControllerTest, AnchorAlignRightArrow) {
+ [[controller_ bubble] setArrowLocation:info_bubble::kTopRight];
+ [[controller_ bubble] setAlignment:info_bubble::kAlignArrowToAnchor];
+ [controller_ showWindow:nil];
+
+ NSRect frame = [[controller_ window] frame];
+ // Make sure the bubble size hasn't changed.
+ EXPECT_EQ(frame.size.width, kBubbleWindowWidth);
+ EXPECT_EQ(frame.size.height, kBubbleWindowHeight);
+ // Make sure the bubble arrow points to the anchor.
+ EXPECT_EQ(NSMaxX(frame) - info_bubble::kBubbleArrowXOffset -
+ floorf(info_bubble::kBubbleArrowWidth / 2.0), kAnchorPointX);
+ EXPECT_GE(NSMaxY(frame), kAnchorPointY);
+}
diff --git a/chrome/browser/ui/cocoa/browser_window_cocoa.mm b/chrome/browser/ui/cocoa/browser_window_cocoa.mm
index 442efe7..9a8726f 100644
--- a/chrome/browser/ui/cocoa/browser_window_cocoa.mm
+++ b/chrome/browser/ui/cocoa/browser_window_cocoa.mm
@@ -28,6 +28,7 @@
#import "chrome/browser/ui/cocoa/download/download_shelf_controller.h"
#include "chrome/browser/ui/cocoa/find_bar/find_bar_bridge.h"
#import "chrome/browser/ui/cocoa/html_dialog_window_controller.h"
+#import "chrome/browser/ui/cocoa/info_bubble_view.h"
#import "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h"
#import "chrome/browser/ui/cocoa/nsmenuitem_additions.h"
#include "chrome/browser/ui/cocoa/page_info_window.h"
@@ -612,6 +613,7 @@ void BrowserWindowCocoa::ShowAvatarBubble(TabContents* tab_contents,
AvatarMenuBubbleController* menu =
[[AvatarMenuBubbleController alloc] initWithBrowser:browser_
anchoredAt:point];
+ [[menu bubble] setAlignment:info_bubble::kAlignEdgeToAnchorEdge];
[menu showWindow:nil];
}
diff --git a/chrome/browser/ui/cocoa/info_bubble_view.h b/chrome/browser/ui/cocoa/info_bubble_view.h
index 1d5ab28..8463da2 100644
--- a/chrome/browser/ui/cocoa/info_bubble_view.h
+++ b/chrome/browser/ui/cocoa/info_bubble_view.h
@@ -21,6 +21,13 @@ enum BubbleArrowLocation {
kNoArrow,
};
+enum BubbleAlignment {
+ // The tip of the arrow points to the anchor point.
+ kAlignArrowToAnchor,
+ // The edge nearest to the arrow is lined up with the anchor point.
+ kAlignEdgeToAnchorEdge,
+};
+
} // namespace info_bubble
// Content view for a bubble with an arrow showing arbitrary content.
@@ -28,9 +35,11 @@ enum BubbleArrowLocation {
@interface InfoBubbleView : NSView {
@private
info_bubble::BubbleArrowLocation arrowLocation_;
+ info_bubble::BubbleAlignment alignment_;
}
@property(assign, nonatomic) info_bubble::BubbleArrowLocation arrowLocation;
+@property(assign, nonatomic) info_bubble::BubbleAlignment alignment;
// Returns the point location in view coordinates of the tip of the arrow.
- (NSPoint)arrowTip;
diff --git a/chrome/browser/ui/cocoa/info_bubble_view.mm b/chrome/browser/ui/cocoa/info_bubble_view.mm
index 39799ef..a8cd6ae 100644
--- a/chrome/browser/ui/cocoa/info_bubble_view.mm
+++ b/chrome/browser/ui/cocoa/info_bubble_view.mm
@@ -10,10 +10,12 @@
@implementation InfoBubbleView
@synthesize arrowLocation = arrowLocation_;
+@synthesize alignment = alignment_;
- (id)initWithFrame:(NSRect)frameRect {
if ((self = [super initWithFrame:frameRect])) {
arrowLocation_ = info_bubble::kTopLeft;
+ alignment_ = info_bubble::kAlignArrowToAnchor;
}
return self;
}
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index 59cc637..07b9c8c 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -1660,6 +1660,7 @@
'browser/ui/cocoa/applescript/bookmark_item_applescript_unittest.mm',
'browser/ui/cocoa/background_gradient_view_unittest.mm',
'browser/ui/cocoa/background_tile_view_unittest.mm',
+ 'browser/ui/cocoa/base_bubble_controller_unittest.mm',
'browser/ui/cocoa/bookmarks/bookmark_all_tabs_controller_unittest.mm',
'browser/ui/cocoa/bookmarks/bookmark_bar_bridge_unittest.mm',
'browser/ui/cocoa/bookmarks/bookmark_bar_controller_unittest.mm',