summaryrefslogtreecommitdiffstats
path: root/chrome/browser/cocoa
diff options
context:
space:
mode:
authoravi@google.com <avi@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-19 17:40:18 +0000
committeravi@google.com <avi@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-19 17:40:18 +0000
commit2789a420ecc39b2e446bd2f81e2e66764c5c38ab (patch)
tree203f6106aeeb535bc557d53e10fceb8aa5fa813a /chrome/browser/cocoa
parent88a3eccb5605fc9224ce59c76473b7aae2c31bc8 (diff)
downloadchromium_src-2789a420ecc39b2e446bd2f81e2e66764c5c38ab.zip
chromium_src-2789a420ecc39b2e446bd2f81e2e66764c5c38ab.tar.gz
chromium_src-2789a420ecc39b2e446bd2f81e2e66764c5c38ab.tar.bz2
Make the status bubble avoid the mouse.
Review URL: http://codereview.chromium.org/42398 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@12103 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/cocoa')
-rw-r--r--chrome/browser/cocoa/status_bubble_mac.h3
-rw-r--r--chrome/browser/cocoa/status_bubble_mac.mm101
2 files changed, 96 insertions, 8 deletions
diff --git a/chrome/browser/cocoa/status_bubble_mac.h b/chrome/browser/cocoa/status_bubble_mac.h
index 6581ac7..a0c1ec1 100644
--- a/chrome/browser/cocoa/status_bubble_mac.h
+++ b/chrome/browser/cocoa/status_bubble_mac.h
@@ -45,6 +45,9 @@ class StatusBubbleMac : public StatusBubble {
// The url we want to display when there is no status text to display.
NSString* url_text_;
+
+ // How vertically offset the bubble is from its root position.
+ int offset_;
};
#endif // #ifndef CHROME_BROWSER_COCOA_STATUS_BUBBLE_MAC_H_
diff --git a/chrome/browser/cocoa/status_bubble_mac.mm b/chrome/browser/cocoa/status_bubble_mac.mm
index b6b4922..b423fb4 100644
--- a/chrome/browser/cocoa/status_bubble_mac.mm
+++ b/chrome/browser/cocoa/status_bubble_mac.mm
@@ -16,6 +16,10 @@ const int kWindowHeight = 18;
// The width of the bubble in relation to the width of the parent window.
const float kWindowWidthPercent = 1.0f/3.0f;
+// How close the mouse can get to the infobubble before it starts sliding
+// off-screen.
+const int kMousePadding = 20;
+
const int kTextPadding = 3;
const int kTextPositionX = 4;
const int kTextPositionY = 2;
@@ -33,16 +37,23 @@ const int kHideFadeDuration = 0.200f;
}
// TODO(avi):
-// - move in response to overlapping mouse
// - do display delay
// - figure out why the show/fade durations aren't working
+enum BubbleStyle {
+ STYLE_BOTTOM, // Hanging off the bottom of the parent window
+ STYLE_FLOATING, // Between BOTTOM and STANDARD
+ STYLE_STANDARD // Nestled in the corner of the parent window
+};
+
@interface StatusBubbleViewCocoa : NSView {
@private
NSString* content_;
+ BubbleStyle style_;
}
- (void)setContent:(NSString*)content;
+- (void)setStyle:(BubbleStyle)style;
- (NSFont*)font;
@end
@@ -127,6 +138,55 @@ void StatusBubbleMac::Hide() {
}
void StatusBubbleMac::MouseMoved() {
+ if (!window_)
+ return;
+
+ NSPoint cursor_location = [NSEvent mouseLocation];
+ --cursor_location.y; // docs say the y coord starts at 1 not 0; don't ask why
+
+ // Get the normal position of the frame.
+ NSRect window_frame = [window_ frame];
+ window_frame.origin = [parent_ frame].origin;
+
+ // Get the cursor position relative to the popup.
+ cursor_location.x -= NSMaxX(window_frame);
+ cursor_location.y -= NSMaxY(window_frame);
+
+ // If the mouse is in a position where we think it would move the
+ // status bubble, figure out where and how the bubble should be moved.
+ if (cursor_location.y < kMousePadding &&
+ cursor_location.x < kMousePadding) {
+ int offset = kMousePadding - cursor_location.y;
+
+ // Make the movement non-linear.
+ offset = offset * offset / kMousePadding;
+
+ // When the mouse is entering from the right, we want the offset to be
+ // scaled by how horizontally far away the cursor is from the bubble.
+ if (cursor_location.x > 0) {
+ offset = offset * ((kMousePadding - cursor_location.x) / kMousePadding);
+ }
+
+ // Cap the offset and change the visual presentation of the bubble
+ // depending on where it ends up (so that rounded corners square off
+ // and mate to the edges of the tab content).
+ if (offset >= NSHeight(window_frame)) {
+ offset = NSHeight(window_frame);
+ [[window_ contentView] setStyle:STYLE_BOTTOM];
+ } else if (offset > 0) {
+ [[window_ contentView] setStyle:STYLE_FLOATING];
+ } else {
+ [[window_ contentView] setStyle:STYLE_STANDARD];
+ }
+
+ offset_ = offset;
+ window_frame.origin.y -= offset;
+ [window_ setFrame:window_frame display:YES];
+ } else {
+ offset_ = 0;
+ [[window_ contentView] setStyle:STYLE_STANDARD];
+ [window_ setFrame:window_frame display:YES];
+ }
}
void StatusBubbleMac::Create() {
@@ -147,7 +207,7 @@ void StatusBubbleMac::Create() {
[window_ setOpaque:NO];
[window_ setHasShadow:NO];
- NSView* view =
+ StatusBubbleViewCocoa* view =
[[[StatusBubbleViewCocoa alloc] initWithFrame:NSZeroRect] autorelease];
[window_ setContentView:view];
@@ -155,6 +215,10 @@ void StatusBubbleMac::Create() {
[window_ setAlphaValue:0.0f];
[window_ orderFront:nil];
+
+ offset_ = 0;
+ [view setStyle:STYLE_STANDARD];
+ MouseMoved();
}
void StatusBubbleMac::FadeIn() {
@@ -184,17 +248,38 @@ void StatusBubbleMac::FadeOut() {
[self setNeedsDisplay:YES];
}
+- (void)setStyle:(BubbleStyle)style {
+ style_ = style;
+ [self setNeedsDisplay:YES];
+}
+
- (NSFont*)font {
return [NSFont systemFontOfSize:[NSFont smallSystemFontSize]];
}
- (void)drawRect:(NSRect)rect {
- // Decide on which corners to round
- // TODO(avi): decide properly
- float tl_radius = 0.0f;
- float tr_radius = kBubbleCornerRadius;
- float bl_radius = 0.0f;
- float br_radius = 0.0f;
+ float tl_radius, tr_radius, bl_radius, br_radius;
+
+ switch (style_) {
+ case STYLE_BOTTOM:
+ tl_radius = 0.0f;
+ tr_radius = 0.0f;
+ bl_radius = kBubbleCornerRadius;
+ br_radius = kBubbleCornerRadius;
+ break;
+ case STYLE_FLOATING:
+ tl_radius = 0.0f;
+ tr_radius = kBubbleCornerRadius;
+ bl_radius = kBubbleCornerRadius;
+ br_radius = kBubbleCornerRadius;
+ break;
+ case STYLE_STANDARD:
+ tl_radius = 0.0f;
+ tr_radius = kBubbleCornerRadius;
+ bl_radius = 0.0f;
+ br_radius = 0.0f;
+ break;
+ }
// Background / Edge