Index: ash/system/tray/system_tray_bubble.cc |
diff --git a/ash/system/tray/system_tray_bubble.cc b/ash/system/tray/system_tray_bubble.cc |
index 7145615c1cc0a4fe8ef09f0696fd2e7dc954d2cf..4b1a26d5495d694aa1b1e0ebfe15cc3c1f3d0d61 100644 |
--- a/ash/system/tray/system_tray_bubble.cc |
+++ b/ash/system/tray/system_tray_bubble.cc |
@@ -34,12 +34,15 @@ namespace { |
const int kShadowThickness = 4; |
-const int kLeftPadding = 4; |
const int kBottomLineHeight = 1; |
+const int kSystemTrayBubbleHorizontalInset = 1; |
+const int kSystemTrayBubbleVerticalInset = 1; |
+ |
const int kArrowHeight = 10; |
const int kArrowWidth = 20; |
const int kArrowPaddingFromRight = 20; |
+const int kMinArrowOffset = 12; |
const int kAnimationDurationForPopupMS = 200; |
@@ -128,20 +131,31 @@ class TrayPopupItemContainer : public views::View { |
DISALLOW_COPY_AND_ASSIGN(TrayPopupItemContainer); |
}; |
-class SystemTrayBubbleBackground : public views::Background { |
+class SystemTrayBubbleBorder : public views::BubbleBorder { |
public: |
- explicit SystemTrayBubbleBackground(views::View* owner) |
- : owner_(owner) { |
+ SystemTrayBubbleBorder(views::View* owner, |
+ views::BubbleBorder::ArrowLocation arrow_location, |
+ int arrow_offset) |
+ : views::BubbleBorder(arrow_location, |
+ views::BubbleBorder::NO_SHADOW), |
+ owner_(owner), |
+ arrow_offset_(std::max(arrow_offset, kMinArrowOffset)) { |
+ set_alignment(views::BubbleBorder::ALIGN_EDGE_TO_ANCHOR_EDGE); |
} |
- virtual ~SystemTrayBubbleBackground() {} |
+ virtual ~SystemTrayBubbleBorder() {} |
private: |
- // Overridden from views::Background. |
- virtual void Paint(gfx::Canvas* canvas, views::View* view) const OVERRIDE { |
+ void PaintChildBorder(gfx::Canvas* canvas) const { |
+ gfx::Insets insets; |
+ GetInsets(&insets); |
+ canvas->Save(); |
+ canvas->Translate(gfx::Point(insets.left(), insets.top())); |
views::View* last_view = NULL; |
for (int i = 0; i < owner_->child_count(); i++) { |
views::View* v = owner_->child_at(i); |
+ if (!v->visible()) |
+ continue; |
if (!v->border()) { |
canvas->DrawLine(gfx::Point(v->x(), v->y() - 1), |
@@ -162,34 +176,9 @@ class SystemTrayBubbleBackground : public views::Background { |
kBorderDarkColor); |
last_view = v; |
} |
+ canvas->Restore(); |
} |
- views::View* owner_; |
- |
- DISALLOW_COPY_AND_ASSIGN(SystemTrayBubbleBackground); |
-}; |
- |
-class SystemTrayBubbleBorder : public views::BubbleBorder { |
- public: |
- enum ArrowType { |
- ARROW_TYPE_NONE, |
- ARROW_TYPE_BOTTOM, |
- }; |
- |
- SystemTrayBubbleBorder(views::View* owner, |
- ArrowType arrow_type, |
- int arrow_offset) |
- : views::BubbleBorder(views::BubbleBorder::BOTTOM_RIGHT, |
- views::BubbleBorder::NO_SHADOW), |
- owner_(owner), |
- arrow_type_(arrow_type), |
- arrow_offset_(arrow_offset) { |
- set_alignment(views::BubbleBorder::ALIGN_EDGE_TO_ANCHOR_EDGE); |
- } |
- |
- virtual ~SystemTrayBubbleBorder() {} |
- |
- private: |
// Overridden from views::Border. |
virtual void Paint(const views::View& view, |
gfx::Canvas* canvas) const OVERRIDE { |
@@ -198,43 +187,67 @@ class SystemTrayBubbleBorder : public views::BubbleBorder { |
DrawBlurredShadowAroundView(canvas, 0, owner_->height(), owner_->width(), |
inset); |
+ PaintChildBorder(canvas); |
+ |
// Draw the bottom line. |
int y = owner_->height() + 1; |
- canvas->FillRect(gfx::Rect(kLeftPadding, y, owner_->width(), |
+ canvas->FillRect(gfx::Rect(inset.left(), y, owner_->width(), |
kBottomLineHeight), kBorderDarkColor); |
- if (!Shell::GetInstance()->shelf()->IsVisible()) |
+ if (!Shell::GetInstance()->shelf()->IsVisible() || |
+ arrow_location() == views::BubbleBorder::NONE) |
return; |
- // Draw the arrow. |
- if (arrow_type_ == ARROW_TYPE_BOTTOM) { |
+ // Draw the arrow after drawing child borders, so that the arrow can cover |
+ // the its overlap section with child border. |
+ SkPath path; |
+ if (arrow_location() == views::BubbleBorder::BOTTOM_RIGHT) { |
int tip_x = base::i18n::IsRTL() ? arrow_offset_ : |
owner_->width() - arrow_offset_; |
int left_base_x = tip_x - kArrowWidth / 2; |
int left_base_y = y; |
int tip_y = left_base_y + kArrowHeight; |
- |
- SkPath path; |
path.incReserve(4); |
sadrul
2012/05/17 23:30:29
Move this line after line 203 and remove from othe
jennyz
2012/05/18 00:00:42
Done.
|
path.moveTo(SkIntToScalar(left_base_x), SkIntToScalar(left_base_y)); |
path.lineTo(SkIntToScalar(tip_x), SkIntToScalar(tip_y)); |
path.lineTo(SkIntToScalar(left_base_x + kArrowWidth), |
SkIntToScalar(left_base_y)); |
+ } else if (arrow_location() == views::BubbleBorder::LEFT_BOTTOM) { |
+ int tip_y = y - arrow_offset_; |
+ int top_base_y = tip_y - kArrowWidth / 2; |
+ int top_base_x = inset.left() + kSystemTrayBubbleHorizontalInset; |
+ int tip_x = top_base_x - kArrowHeight; |
+ path.incReserve(4); |
+ path.moveTo(SkIntToScalar(top_base_x), SkIntToScalar(top_base_y)); |
+ path.lineTo(SkIntToScalar(tip_x), SkIntToScalar(tip_y)); |
+ path.lineTo(SkIntToScalar(top_base_x), |
+ SkIntToScalar(top_base_y + kArrowWidth)); |
+ } else if (arrow_location() == views::BubbleBorder::RIGHT_BOTTOM){ |
+ int tip_y = y - arrow_offset_; |
sadrul
2012/05/17 23:30:29
spacing in this block seems off
jennyz
2012/05/18 00:00:42
Done.
|
+ int top_base_y = tip_y - kArrowWidth / 2; |
+ int top_base_x = inset.left() + owner_->width() - |
+ kSystemTrayBubbleHorizontalInset; |
+ int tip_x = top_base_x + kArrowHeight; |
+ path.incReserve(4); |
+ path.moveTo(SkIntToScalar(top_base_x), SkIntToScalar(top_base_y)); |
+ path.lineTo(SkIntToScalar(tip_x), SkIntToScalar(tip_y)); |
+ path.lineTo(SkIntToScalar(top_base_x), |
+ SkIntToScalar(top_base_y + kArrowWidth)); |
+ } |
- SkPaint paint; |
- paint.setStyle(SkPaint::kFill_Style); |
- paint.setColor(kHeaderBackgroundColorDark); |
- canvas->DrawPath(path, paint); |
+ SkPaint paint; |
+ paint.setStyle(SkPaint::kFill_Style); |
+ paint.setColor(kHeaderBackgroundColorDark); |
+ canvas->DrawPath(path, paint); |
+ |
+ // Now draw the arrow border. |
+ paint.setStyle(SkPaint::kStroke_Style); |
+ paint.setColor(kBorderDarkColor); |
+ canvas->DrawPath(path, paint); |
- // Now draw the arrow border. |
- paint.setStyle(SkPaint::kStroke_Style); |
- paint.setColor(kBorderDarkColor); |
- canvas->DrawPath(path, paint); |
- } |
} |
views::View* owner_; |
- ArrowType arrow_type_; |
const int arrow_offset_; |
DISALLOW_COPY_AND_ASSIGN(SystemTrayBubbleBorder); |
@@ -247,9 +260,10 @@ namespace internal { |
// SystemTrayBubbleView |
SystemTrayBubbleView::SystemTrayBubbleView(views::View* anchor, |
- SystemTrayBubble* host, |
- bool can_activate) |
- : views::BubbleDelegateView(anchor, views::BubbleBorder::BOTTOM_RIGHT), |
+ views::BubbleBorder::ArrowLocation arrow_location, |
+ SystemTrayBubble* host, |
+ bool can_activate) |
+ : views::BubbleDelegateView(anchor, arrow_location), |
host_(host), |
can_activate_(can_activate) { |
set_margin(0); |
@@ -275,22 +289,27 @@ void SystemTrayBubbleView::UpdateAnchor() { |
void SystemTrayBubbleView::Init() { |
views::BoxLayout* layout = |
- new views::BoxLayout(views::BoxLayout::kVertical, 1, 1, 1); |
+ new views::BoxLayout(views::BoxLayout::kVertical, |
+ kSystemTrayBubbleHorizontalInset, |
+ kSystemTrayBubbleVerticalInset, |
+ 1); |
layout->set_spread_blank_space(true); |
SetLayoutManager(layout); |
- set_background(new SystemTrayBubbleBackground(this)); |
+ set_background(NULL); |
} |
gfx::Rect SystemTrayBubbleView::GetAnchorRect() { |
gfx::Rect rect; |
if (host_) |
rect = host_->GetAnchorRect(); |
+ // TODO(jennyz): May need to add left/right alignment in the following code. |
if (rect.IsEmpty()) { |
rect = gfx::Screen::GetPrimaryMonitor().bounds(); |
- rect = gfx::Rect(base::i18n::IsRTL() ? kPaddingFromRightEdgeOfScreen : |
- rect.width() - kPaddingFromRightEdgeOfScreen, |
- rect.height() - kPaddingFromBottomOfScreen, |
- 0, 0); |
+ rect = gfx::Rect( |
+ base::i18n::IsRTL() ? kPaddingFromRightEdgeOfScreenBottomAlignment : |
+ rect.width() - kPaddingFromRightEdgeOfScreenBottomAlignment, |
+ rect.height() - kPaddingFromBottomOfScreenBottomAlignment, |
+ 0, 0); |
} |
return rect; |
} |
@@ -378,8 +397,20 @@ void SystemTrayBubble::UpdateView( |
void SystemTrayBubble::InitView(const InitParams& init_params) { |
DCHECK(bubble_view_ == NULL); |
anchor_type_ = init_params.anchor_type; |
+ views::BubbleBorder::ArrowLocation arrow_location; |
+ if (anchor_type_ == ANCHOR_TYPE_TRAY) { |
+ if (tray_->shelf_alignment() == SHELF_ALIGNMENT_BOTTOM) { |
+ arrow_location = views::BubbleBorder::BOTTOM_RIGHT; |
+ } else if (tray_->shelf_alignment() == SHELF_ALIGNMENT_LEFT) { |
+ arrow_location = views::BubbleBorder::LEFT_BOTTOM; |
+ } else { |
+ arrow_location = views::BubbleBorder::RIGHT_BOTTOM; |
+ } |
+ } else { |
+ arrow_location = views::BubbleBorder::NONE; |
+ } |
bubble_view_ = new SystemTrayBubbleView( |
- init_params.anchor, this, init_params.can_activate); |
+ init_params.anchor, arrow_location, this, init_params.can_activate); |
if (bubble_type_ == BUBBLE_TYPE_NOTIFICATION) |
bubble_view_->set_close_on_deactivate(false); |
@@ -391,14 +422,8 @@ void SystemTrayBubble::InitView(const InitParams& init_params) { |
// Must occur after call to CreateBubble() |
bubble_view_->SetAlignment(views::BubbleBorder::ALIGN_EDGE_TO_ANCHOR_EDGE); |
bubble_widget_->non_client_view()->frame_view()->set_background(NULL); |
- SystemTrayBubbleBorder::ArrowType arrow_type; |
- if (anchor_type_ == ANCHOR_TYPE_TRAY) |
- arrow_type = SystemTrayBubbleBorder::ARROW_TYPE_BOTTOM; |
- else |
- arrow_type = SystemTrayBubbleBorder::ARROW_TYPE_NONE; |
- |
SystemTrayBubbleBorder* bubble_border = new SystemTrayBubbleBorder( |
- bubble_view_, arrow_type, init_params.arrow_offset); |
+ bubble_view_, arrow_location, init_params.arrow_offset); |
bubble_view_->SetBubbleBorder(bubble_border); |
bubble_widget_->AddObserver(this); |
@@ -423,12 +448,23 @@ gfx::Rect SystemTrayBubble::GetAnchorRect() const { |
if (widget->IsVisible()) { |
rect = widget->GetWindowScreenBounds(); |
if (anchor_type_ == ANCHOR_TYPE_TRAY) { |
- rect.Inset( |
- base::i18n::IsRTL() ? kPaddingFromRightEdgeOfScreen : 0, |
- 0, |
- base::i18n::IsRTL() ? 0 : kPaddingFromRightEdgeOfScreen, |
- kPaddingFromBottomOfScreen); |
+ if (tray_->shelf_alignment() == SHELF_ALIGNMENT_BOTTOM) { |
+ rect.Inset( |
+ base::i18n::IsRTL() ? |
+ kPaddingFromRightEdgeOfScreenBottomAlignment : 0, |
+ 0, |
+ base::i18n::IsRTL() ? |
+ 0 : kPaddingFromRightEdgeOfScreenBottomAlignment, |
+ kPaddingFromBottomOfScreenBottomAlignment); |
+ } else if (tray_->shelf_alignment() == SHELF_ALIGNMENT_LEFT) { |
+ rect.Inset(0, 0, kPaddingFromLeftEdgeOfScreenLeftAlignment, |
+ kPaddingFromBottomOfScreenVerticalAlignment); |
+ } else { |
+ rect.Inset(-kPaddingFromRightEdgeOfScreenRightAlignment, |
+ 0, 0, kPaddingFromBottomOfScreenVerticalAlignment); |
+ } |
} else if (anchor_type_ == ANCHOR_TYPE_BUBBLE) { |
+ // TODO(jennyz): add left/right launcher support for notification bubble. |
rect.Inset( |
base::i18n::IsRTL() ? kShadowThickness - 1 : 0, |
0, |