OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ash/system/tray/tray_bubble_view.h" | 5 #include "ash/system/tray/tray_bubble_view.h" |
6 | 6 |
7 #include "ash/shell.h" | 7 #include "ash/shell.h" |
8 #include "ash/shell_window_ids.h" | 8 #include "ash/shell_window_ids.h" |
9 #include "ash/system/tray/tray_constants.h" | 9 #include "ash/system/tray/tray_constants.h" |
10 #include "ash/wm/shelf_layout_manager.h" | 10 #include "ash/wm/shelf_layout_manager.h" |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
74 : views::BubbleBorder(arrow_location, | 74 : views::BubbleBorder(arrow_location, |
75 views::BubbleBorder::NO_SHADOW), | 75 views::BubbleBorder::NO_SHADOW), |
76 owner_(owner), | 76 owner_(owner), |
77 tray_arrow_offset_(arrow_offset) { | 77 tray_arrow_offset_(arrow_offset) { |
78 set_alignment(views::BubbleBorder::ALIGN_EDGE_TO_ANCHOR_EDGE); | 78 set_alignment(views::BubbleBorder::ALIGN_EDGE_TO_ANCHOR_EDGE); |
79 } | 79 } |
80 | 80 |
81 virtual ~TrayBubbleBorder() {} | 81 virtual ~TrayBubbleBorder() {} |
82 | 82 |
83 private: | 83 private: |
| 84 views::Background* FindAppropriateBackground(views::View* view, |
| 85 const gfx::Point& point) const { |
| 86 views::Background* background = NULL; |
| 87 views::View* target = view->GetEventHandlerForPoint(point); |
| 88 for (; target && !background; target = target->parent()) |
| 89 background = target->background(); |
| 90 return background; |
| 91 } |
| 92 |
84 // Overridden from views::BubbleBorder. | 93 // Overridden from views::BubbleBorder. |
85 // Override views::BubbleBorder to set the bubble on top of the anchor when | 94 // Override views::BubbleBorder to set the bubble on top of the anchor when |
86 // it has no arrow. | 95 // it has no arrow. |
87 virtual gfx::Rect GetBounds(const gfx::Rect& position_relative_to, | 96 virtual gfx::Rect GetBounds(const gfx::Rect& position_relative_to, |
88 const gfx::Size& contents_size) const OVERRIDE { | 97 const gfx::Size& contents_size) const OVERRIDE { |
89 if (arrow_location() != NONE) { | 98 if (arrow_location() != NONE) { |
90 return views::BubbleBorder::GetBounds(position_relative_to, | 99 return views::BubbleBorder::GetBounds(position_relative_to, |
91 contents_size); | 100 contents_size); |
92 } | 101 } |
93 | 102 |
(...skipping 21 matching lines...) Expand all Loading... |
115 | 124 |
116 // Draw the bottom line. | 125 // Draw the bottom line. |
117 int y = owner_->height() + inset.top(); | 126 int y = owner_->height() + inset.top(); |
118 canvas->FillRect(gfx::Rect(inset.left(), y, owner_->width(), | 127 canvas->FillRect(gfx::Rect(inset.left(), y, owner_->width(), |
119 kBottomLineHeight), kBorderDarkColor); | 128 kBottomLineHeight), kBorderDarkColor); |
120 | 129 |
121 if (!Shell::GetInstance()->shelf()->IsVisible() || | 130 if (!Shell::GetInstance()->shelf()->IsVisible() || |
122 arrow_location() == views::BubbleBorder::NONE) | 131 arrow_location() == views::BubbleBorder::NONE) |
123 return; | 132 return; |
124 | 133 |
| 134 gfx::Point arrow_reference; |
| 135 |
125 // Draw the arrow after drawing child borders, so that the arrow can cover | 136 // Draw the arrow after drawing child borders, so that the arrow can cover |
126 // the its overlap section with child border. | 137 // the its overlap section with child border. |
127 SkPath path; | 138 SkPath path; |
128 path.incReserve(4); | 139 path.incReserve(4); |
129 if (arrow_location() == views::BubbleBorder::BOTTOM_RIGHT) { | 140 if (arrow_location() == views::BubbleBorder::BOTTOM_RIGHT) { |
130 int tip_x = base::i18n::IsRTL() ? tray_arrow_offset_ : | 141 int tip_x = base::i18n::IsRTL() ? tray_arrow_offset_ : |
131 owner_->width() - tray_arrow_offset_; | 142 owner_->width() - tray_arrow_offset_; |
132 tip_x = std::min(std::max(kArrowMinOffset, tip_x), | 143 tip_x = std::min(std::max(kArrowMinOffset, tip_x), |
133 owner_->width() - kArrowMinOffset); | 144 owner_->width() - kArrowMinOffset); |
134 int left_base_x = tip_x - kArrowWidth / 2; | 145 int left_base_x = tip_x - kArrowWidth / 2; |
135 int left_base_y = y; | 146 int left_base_y = y; |
136 int tip_y = left_base_y + kArrowHeight; | 147 int tip_y = left_base_y + kArrowHeight; |
137 path.moveTo(SkIntToScalar(left_base_x), SkIntToScalar(left_base_y)); | 148 path.moveTo(SkIntToScalar(left_base_x), SkIntToScalar(left_base_y)); |
138 path.lineTo(SkIntToScalar(tip_x), SkIntToScalar(tip_y)); | 149 path.lineTo(SkIntToScalar(tip_x), SkIntToScalar(tip_y)); |
139 path.lineTo(SkIntToScalar(left_base_x + kArrowWidth), | 150 path.lineTo(SkIntToScalar(left_base_x + kArrowWidth), |
140 SkIntToScalar(left_base_y)); | 151 SkIntToScalar(left_base_y)); |
| 152 arrow_reference.SetPoint(tip_x, left_base_y - kArrowHeight); |
141 } else { | 153 } else { |
142 int tip_y = y - tray_arrow_offset_; | 154 int tip_y = y - tray_arrow_offset_; |
143 tip_y = std::min(std::max(kArrowMinOffset, tip_y), | 155 tip_y = std::min(std::max(kArrowMinOffset, tip_y), |
144 owner_->height() - kArrowMinOffset); | 156 owner_->height() - kArrowMinOffset); |
145 int top_base_y = tip_y - kArrowWidth / 2; | 157 int top_base_y = tip_y - kArrowWidth / 2; |
146 int top_base_x, tip_x; | 158 int top_base_x, tip_x; |
147 if (arrow_location() == views::BubbleBorder::LEFT_BOTTOM) { | 159 if (arrow_location() == views::BubbleBorder::LEFT_BOTTOM) { |
148 top_base_x = inset.left() + kSystemTrayBubbleHorizontalInset; | 160 top_base_x = inset.left() + kSystemTrayBubbleHorizontalInset; |
149 tip_x = top_base_x - kArrowHeight; | 161 tip_x = top_base_x - kArrowHeight; |
| 162 arrow_reference.SetPoint(top_base_x + kArrowHeight, tip_y); |
150 } else { | 163 } else { |
151 DCHECK(arrow_location() == views::BubbleBorder::RIGHT_BOTTOM); | 164 DCHECK(arrow_location() == views::BubbleBorder::RIGHT_BOTTOM); |
152 top_base_x = inset.left() + owner_->width() - | 165 top_base_x = inset.left() + owner_->width() - |
153 kSystemTrayBubbleHorizontalInset; | 166 kSystemTrayBubbleHorizontalInset; |
154 tip_x = top_base_x + kArrowHeight; | 167 tip_x = top_base_x + kArrowHeight; |
| 168 arrow_reference.SetPoint(top_base_x - kArrowHeight, tip_y); |
155 } | 169 } |
156 path.moveTo(SkIntToScalar(top_base_x), SkIntToScalar(top_base_y)); | 170 path.moveTo(SkIntToScalar(top_base_x), SkIntToScalar(top_base_y)); |
157 path.lineTo(SkIntToScalar(tip_x), SkIntToScalar(tip_y)); | 171 path.lineTo(SkIntToScalar(tip_x), SkIntToScalar(tip_y)); |
158 path.lineTo(SkIntToScalar(top_base_x), | 172 path.lineTo(SkIntToScalar(top_base_x), |
159 SkIntToScalar(top_base_y + kArrowWidth)); | 173 SkIntToScalar(top_base_y + kArrowWidth)); |
160 } | 174 } |
161 | 175 |
| 176 views::Background* background = FindAppropriateBackground(owner_, |
| 177 arrow_reference); |
| 178 |
162 SkPaint paint; | 179 SkPaint paint; |
163 paint.setStyle(SkPaint::kFill_Style); | 180 paint.setStyle(SkPaint::kFill_Style); |
164 paint.setColor(kHeaderBackgroundColorDark); | 181 paint.setColor(background ? background->get_color() : kBackgroundColor); |
165 canvas->DrawPath(path, paint); | 182 canvas->DrawPath(path, paint); |
166 | 183 |
167 // Now draw the arrow border. | 184 // Now draw the arrow border. |
168 paint.setStyle(SkPaint::kStroke_Style); | 185 paint.setStyle(SkPaint::kStroke_Style); |
169 paint.setColor(kBorderDarkColor); | 186 paint.setColor(kBorderDarkColor); |
170 canvas->DrawPath(path, paint); | 187 canvas->DrawPath(path, paint); |
171 | 188 |
172 } | 189 } |
173 | 190 |
174 views::View* owner_; | 191 views::View* owner_; |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
358 return; | 375 return; |
359 } | 376 } |
360 // Handle clicking outside the bubble and tray. We don't block the event, so | 377 // Handle clicking outside the bubble and tray. We don't block the event, so |
361 // it will also be handled by whatever widget was clicked on. | 378 // it will also be handled by whatever widget was clicked on. |
362 OnClickedOutsideView(); | 379 OnClickedOutsideView(); |
363 } | 380 } |
364 | 381 |
365 | 382 |
366 } // namespace internal | 383 } // namespace internal |
367 } // namespace ash | 384 } // namespace ash |
OLD | NEW |