| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "ui/gfx/insets.h" | |
| 6 #include "ui/views/bubble/bubble_border.h" | |
| 7 #include "ui/views/bubble/bubble_frame_view.h" | |
| 8 #include "ui/views/test/views_test_base.h" | |
| 9 #include "ui/views/widget/widget.h" | |
| 10 | |
| 11 namespace views { | |
| 12 | |
| 13 typedef ViewsTestBase BubbleFrameViewTest; | |
| 14 | |
| 15 namespace { | |
| 16 | |
| 17 const BubbleBorder::Arrow kArrow = BubbleBorder::TOP_LEFT; | |
| 18 const SkColor kColor = SK_ColorRED; | |
| 19 const int kMargin = 6; | |
| 20 | |
| 21 class TestBubbleFrameView : public BubbleFrameView { | |
| 22 public: | |
| 23 TestBubbleFrameView() | |
| 24 : BubbleFrameView(gfx::Insets(kMargin, kMargin, kMargin, kMargin)), | |
| 25 available_bounds_(gfx::Rect(0, 0, 1000, 1000)) { | |
| 26 SetBubbleBorder(scoped_ptr<views::BubbleBorder>( | |
| 27 new BubbleBorder(kArrow, BubbleBorder::NO_SHADOW, kColor))); | |
| 28 } | |
| 29 virtual ~TestBubbleFrameView() {} | |
| 30 | |
| 31 // BubbleFrameView overrides: | |
| 32 virtual gfx::Rect GetAvailableScreenBounds(const gfx::Rect& rect) override { | |
| 33 return available_bounds_; | |
| 34 } | |
| 35 | |
| 36 private: | |
| 37 gfx::Rect available_bounds_; | |
| 38 | |
| 39 DISALLOW_COPY_AND_ASSIGN(TestBubbleFrameView); | |
| 40 }; | |
| 41 | |
| 42 } // namespace | |
| 43 | |
| 44 TEST_F(BubbleFrameViewTest, GetBoundsForClientView) { | |
| 45 TestBubbleFrameView frame; | |
| 46 EXPECT_EQ(kArrow, frame.bubble_border()->arrow()); | |
| 47 EXPECT_EQ(kColor, frame.bubble_border()->background_color()); | |
| 48 | |
| 49 int margin_x = frame.content_margins().left(); | |
| 50 int margin_y = frame.content_margins().top(); | |
| 51 gfx::Insets insets = frame.bubble_border()->GetInsets(); | |
| 52 EXPECT_EQ(insets.left() + margin_x, frame.GetBoundsForClientView().x()); | |
| 53 EXPECT_EQ(insets.top() + margin_y, frame.GetBoundsForClientView().y()); | |
| 54 } | |
| 55 | |
| 56 // Tests that the arrow is mirrored as needed to better fit the screen. | |
| 57 TEST_F(BubbleFrameViewTest, GetUpdatedWindowBounds) { | |
| 58 TestBubbleFrameView frame; | |
| 59 gfx::Rect window_bounds; | |
| 60 | |
| 61 gfx::Insets insets = frame.bubble_border()->GetInsets(); | |
| 62 int xposition = 95 - insets.width(); | |
| 63 | |
| 64 // Test that the info bubble displays normally when it fits. | |
| 65 frame.bubble_border()->set_arrow(BubbleBorder::TOP_LEFT); | |
| 66 window_bounds = frame.GetUpdatedWindowBounds( | |
| 67 gfx::Rect(100, 100, 50, 50), // |anchor_rect| | |
| 68 gfx::Size(500, 500), // |client_size| | |
| 69 true); // |adjust_if_offscreen| | |
| 70 EXPECT_EQ(BubbleBorder::TOP_LEFT, frame.bubble_border()->arrow()); | |
| 71 EXPECT_GT(window_bounds.x(), xposition); | |
| 72 EXPECT_GT(window_bounds.y(), 100 + 50 - 10); // -10 to roughly compensate for | |
| 73 // arrow overlap. | |
| 74 | |
| 75 // Test bubble not fitting on left. | |
| 76 frame.bubble_border()->set_arrow(BubbleBorder::TOP_RIGHT); | |
| 77 window_bounds = frame.GetUpdatedWindowBounds( | |
| 78 gfx::Rect(100, 100, 50, 50), // |anchor_rect| | |
| 79 gfx::Size(500, 500), // |client_size| | |
| 80 true); // |adjust_if_offscreen| | |
| 81 EXPECT_EQ(BubbleBorder::TOP_LEFT, frame.bubble_border()->arrow()); | |
| 82 EXPECT_GT(window_bounds.x(), xposition); | |
| 83 EXPECT_GT(window_bounds.y(), 100 + 50 - 10); // -10 to roughly compensate for | |
| 84 // arrow overlap. | |
| 85 | |
| 86 // Test bubble not fitting on left or top. | |
| 87 frame.bubble_border()->set_arrow(BubbleBorder::BOTTOM_RIGHT); | |
| 88 window_bounds = frame.GetUpdatedWindowBounds( | |
| 89 gfx::Rect(100, 100, 50, 50), // |anchor_rect| | |
| 90 gfx::Size(500, 500), // |client_size| | |
| 91 true); // |adjust_if_offscreen| | |
| 92 EXPECT_EQ(BubbleBorder::TOP_LEFT, frame.bubble_border()->arrow()); | |
| 93 EXPECT_GT(window_bounds.x(), xposition); | |
| 94 EXPECT_GT(window_bounds.y(), 100 + 50 - 10); // -10 to roughly compensate for | |
| 95 // arrow overlap. | |
| 96 | |
| 97 // Test bubble not fitting on top. | |
| 98 frame.bubble_border()->set_arrow(BubbleBorder::BOTTOM_LEFT); | |
| 99 window_bounds = frame.GetUpdatedWindowBounds( | |
| 100 gfx::Rect(100, 100, 50, 50), // |anchor_rect| | |
| 101 gfx::Size(500, 500), // |client_size| | |
| 102 true); // |adjust_if_offscreen| | |
| 103 EXPECT_EQ(BubbleBorder::TOP_LEFT, frame.bubble_border()->arrow()); | |
| 104 EXPECT_GT(window_bounds.x(), xposition); | |
| 105 EXPECT_GT(window_bounds.y(), 100 + 50 - 10); // -10 to roughly compensate for | |
| 106 // arrow overlap. | |
| 107 | |
| 108 // Test bubble not fitting on top and right. | |
| 109 frame.bubble_border()->set_arrow(BubbleBorder::BOTTOM_LEFT); | |
| 110 window_bounds = frame.GetUpdatedWindowBounds( | |
| 111 gfx::Rect(900, 100, 50, 50), // |anchor_rect| | |
| 112 gfx::Size(500, 500), // |client_size| | |
| 113 true); // |adjust_if_offscreen| | |
| 114 EXPECT_EQ(BubbleBorder::TOP_RIGHT, frame.bubble_border()->arrow()); | |
| 115 EXPECT_LT(window_bounds.x(), 900 + 50 - 500); | |
| 116 EXPECT_GT(window_bounds.y(), 100 + 50 - 10); // -10 to roughly compensate for | |
| 117 // arrow overlap. | |
| 118 | |
| 119 // Test bubble not fitting on right. | |
| 120 frame.bubble_border()->set_arrow(BubbleBorder::TOP_LEFT); | |
| 121 window_bounds = frame.GetUpdatedWindowBounds( | |
| 122 gfx::Rect(900, 100, 50, 50), // |anchor_rect| | |
| 123 gfx::Size(500, 500), // |client_size| | |
| 124 true); // |adjust_if_offscreen| | |
| 125 EXPECT_EQ(BubbleBorder::TOP_RIGHT, frame.bubble_border()->arrow()); | |
| 126 EXPECT_LT(window_bounds.x(), 900 + 50 - 500); | |
| 127 EXPECT_GT(window_bounds.y(), 100 + 50 - 10); // -10 to roughly compensate for | |
| 128 // arrow overlap. | |
| 129 | |
| 130 // Test bubble not fitting on bottom and right. | |
| 131 frame.bubble_border()->set_arrow(BubbleBorder::TOP_LEFT); | |
| 132 window_bounds = frame.GetUpdatedWindowBounds( | |
| 133 gfx::Rect(900, 900, 50, 50), // |anchor_rect| | |
| 134 gfx::Size(500, 500), // |client_size| | |
| 135 true); // |adjust_if_offscreen| | |
| 136 EXPECT_EQ(BubbleBorder::BOTTOM_RIGHT, frame.bubble_border()->arrow()); | |
| 137 EXPECT_LT(window_bounds.x(), 900 + 50 - 500); | |
| 138 EXPECT_LT(window_bounds.y(), 900 - 500 - 15); // -15 to roughly compensate | |
| 139 // for arrow height. | |
| 140 | |
| 141 // Test bubble not fitting at the bottom. | |
| 142 frame.bubble_border()->set_arrow(BubbleBorder::TOP_LEFT); | |
| 143 window_bounds = frame.GetUpdatedWindowBounds( | |
| 144 gfx::Rect(100, 900, 50, 50), // |anchor_rect| | |
| 145 gfx::Size(500, 500), // |client_size| | |
| 146 true); // |adjust_if_offscreen| | |
| 147 EXPECT_EQ(BubbleBorder::BOTTOM_LEFT, frame.bubble_border()->arrow()); | |
| 148 // The window should be right aligned with the anchor_rect. | |
| 149 EXPECT_LT(window_bounds.x(), 900 + 50 - 500); | |
| 150 EXPECT_LT(window_bounds.y(), 900 - 500 - 15); // -15 to roughly compensate | |
| 151 // for arrow height. | |
| 152 | |
| 153 // Test bubble not fitting at the bottom and left. | |
| 154 frame.bubble_border()->set_arrow(BubbleBorder::TOP_RIGHT); | |
| 155 window_bounds = frame.GetUpdatedWindowBounds( | |
| 156 gfx::Rect(100, 900, 50, 50), // |anchor_rect| | |
| 157 gfx::Size(500, 500), // |client_size| | |
| 158 true); // |adjust_if_offscreen| | |
| 159 EXPECT_EQ(BubbleBorder::BOTTOM_LEFT, frame.bubble_border()->arrow()); | |
| 160 // The window should be right aligned with the anchor_rect. | |
| 161 EXPECT_LT(window_bounds.x(), 900 + 50 - 500); | |
| 162 EXPECT_LT(window_bounds.y(), 900 - 500 - 15); // -15 to roughly compensate | |
| 163 // for arrow height. | |
| 164 } | |
| 165 | |
| 166 // Tests that the arrow is not moved when the info-bubble does not fit the | |
| 167 // screen but moving it would make matter worse. | |
| 168 TEST_F(BubbleFrameViewTest, GetUpdatedWindowBoundsMirroringFails) { | |
| 169 TestBubbleFrameView frame; | |
| 170 frame.bubble_border()->set_arrow(BubbleBorder::TOP_LEFT); | |
| 171 gfx::Rect window_bounds = frame.GetUpdatedWindowBounds( | |
| 172 gfx::Rect(400, 100, 50, 50), // |anchor_rect| | |
| 173 gfx::Size(500, 700), // |client_size| | |
| 174 true); // |adjust_if_offscreen| | |
| 175 EXPECT_EQ(BubbleBorder::TOP_LEFT, frame.bubble_border()->arrow()); | |
| 176 } | |
| 177 | |
| 178 TEST_F(BubbleFrameViewTest, TestMirroringForCenteredArrow) { | |
| 179 TestBubbleFrameView frame; | |
| 180 | |
| 181 // Test bubble not fitting above the anchor. | |
| 182 frame.bubble_border()->set_arrow(BubbleBorder::BOTTOM_CENTER); | |
| 183 gfx::Rect window_bounds = frame.GetUpdatedWindowBounds( | |
| 184 gfx::Rect(100, 100, 50, 50), // |anchor_rect| | |
| 185 gfx::Size(500, 700), // |client_size| | |
| 186 true); // |adjust_if_offscreen| | |
| 187 EXPECT_EQ(BubbleBorder::TOP_CENTER, frame.bubble_border()->arrow()); | |
| 188 | |
| 189 // Test bubble not fitting below the anchor. | |
| 190 frame.bubble_border()->set_arrow(BubbleBorder::TOP_CENTER); | |
| 191 window_bounds = frame.GetUpdatedWindowBounds( | |
| 192 gfx::Rect(300, 800, 50, 50), // |anchor_rect| | |
| 193 gfx::Size(500, 200), // |client_size| | |
| 194 true); // |adjust_if_offscreen| | |
| 195 EXPECT_EQ(BubbleBorder::BOTTOM_CENTER, frame.bubble_border()->arrow()); | |
| 196 | |
| 197 // Test bubble not fitting to the right of the anchor. | |
| 198 frame.bubble_border()->set_arrow(BubbleBorder::LEFT_CENTER); | |
| 199 window_bounds = frame.GetUpdatedWindowBounds( | |
| 200 gfx::Rect(800, 300, 50, 50), // |anchor_rect| | |
| 201 gfx::Size(200, 500), // |client_size| | |
| 202 true); // |adjust_if_offscreen| | |
| 203 EXPECT_EQ(BubbleBorder::RIGHT_CENTER, frame.bubble_border()->arrow()); | |
| 204 | |
| 205 // Test bubble not fitting to the left of the anchor. | |
| 206 frame.bubble_border()->set_arrow(BubbleBorder::RIGHT_CENTER); | |
| 207 window_bounds = frame.GetUpdatedWindowBounds( | |
| 208 gfx::Rect(100, 300, 50, 50), // |anchor_rect| | |
| 209 gfx::Size(500, 500), // |client_size| | |
| 210 true); // |adjust_if_offscreen| | |
| 211 EXPECT_EQ(BubbleBorder::LEFT_CENTER, frame.bubble_border()->arrow()); | |
| 212 } | |
| 213 | |
| 214 // Test that the arrow will not be mirrored when |adjust_if_offscreen| is false. | |
| 215 TEST_F(BubbleFrameViewTest, GetUpdatedWindowBoundsDontTryMirror) { | |
| 216 TestBubbleFrameView frame; | |
| 217 frame.bubble_border()->set_arrow(BubbleBorder::TOP_RIGHT); | |
| 218 gfx::Rect window_bounds = frame.GetUpdatedWindowBounds( | |
| 219 gfx::Rect(100, 900, 50, 50), // |anchor_rect| | |
| 220 gfx::Size(500, 500), // |client_size| | |
| 221 false); // |adjust_if_offscreen| | |
| 222 EXPECT_EQ(BubbleBorder::TOP_RIGHT, frame.bubble_border()->arrow()); | |
| 223 // The coordinates should be pointing to anchor_rect from TOP_RIGHT. | |
| 224 EXPECT_LT(window_bounds.x(), 100 + 50 - 500); | |
| 225 EXPECT_GT(window_bounds.y(), 900 + 50 - 10); // -10 to roughly compensate for | |
| 226 // arrow overlap. | |
| 227 } | |
| 228 | |
| 229 // Test that the center arrow is moved as needed to fit the screen. | |
| 230 TEST_F(BubbleFrameViewTest, GetUpdatedWindowBoundsCenterArrows) { | |
| 231 TestBubbleFrameView frame; | |
| 232 gfx::Rect window_bounds; | |
| 233 | |
| 234 // Test that the bubble displays normally when it fits. | |
| 235 frame.bubble_border()->set_arrow(BubbleBorder::TOP_CENTER); | |
| 236 window_bounds = frame.GetUpdatedWindowBounds( | |
| 237 gfx::Rect(500, 100, 50, 50), // |anchor_rect| | |
| 238 gfx::Size(500, 500), // |client_size| | |
| 239 true); // |adjust_if_offscreen| | |
| 240 EXPECT_EQ(BubbleBorder::TOP_CENTER, frame.bubble_border()->arrow()); | |
| 241 EXPECT_EQ(window_bounds.x() + window_bounds.width() / 2, 525); | |
| 242 | |
| 243 frame.bubble_border()->set_arrow(BubbleBorder::BOTTOM_CENTER); | |
| 244 window_bounds = frame.GetUpdatedWindowBounds( | |
| 245 gfx::Rect(500, 900, 50, 50), // |anchor_rect| | |
| 246 gfx::Size(500, 500), // |client_size| | |
| 247 true); // |adjust_if_offscreen| | |
| 248 EXPECT_EQ(BubbleBorder::BOTTOM_CENTER, frame.bubble_border()->arrow()); | |
| 249 EXPECT_EQ(window_bounds.x() + window_bounds.width() / 2, 525); | |
| 250 | |
| 251 frame.bubble_border()->set_arrow(BubbleBorder::LEFT_CENTER); | |
| 252 window_bounds = frame.GetUpdatedWindowBounds( | |
| 253 gfx::Rect(100, 400, 50, 50), // |anchor_rect| | |
| 254 gfx::Size(500, 500), // |client_size| | |
| 255 true); // |adjust_if_offscreen| | |
| 256 EXPECT_EQ(BubbleBorder::LEFT_CENTER, frame.bubble_border()->arrow()); | |
| 257 EXPECT_EQ(window_bounds.y() + window_bounds.height() / 2, 425); | |
| 258 | |
| 259 frame.bubble_border()->set_arrow(BubbleBorder::RIGHT_CENTER); | |
| 260 window_bounds = frame.GetUpdatedWindowBounds( | |
| 261 gfx::Rect(900, 400, 50, 50), // |anchor_rect| | |
| 262 gfx::Size(500, 500), // |client_size| | |
| 263 true); // |adjust_if_offscreen| | |
| 264 EXPECT_EQ(BubbleBorder::RIGHT_CENTER, frame.bubble_border()->arrow()); | |
| 265 EXPECT_EQ(window_bounds.y() + window_bounds.height() / 2, 425); | |
| 266 | |
| 267 // Test bubble not fitting left screen edge. | |
| 268 frame.bubble_border()->set_arrow(BubbleBorder::TOP_CENTER); | |
| 269 window_bounds = frame.GetUpdatedWindowBounds( | |
| 270 gfx::Rect(100, 100, 50, 50), // |anchor_rect| | |
| 271 gfx::Size(500, 500), // |client_size| | |
| 272 true); // |adjust_if_offscreen| | |
| 273 EXPECT_EQ(BubbleBorder::TOP_CENTER, frame.bubble_border()->arrow()); | |
| 274 EXPECT_EQ(window_bounds.x(), 0); | |
| 275 EXPECT_EQ(window_bounds.x() + | |
| 276 frame.bubble_border()->GetArrowOffset(window_bounds.size()), 125); | |
| 277 | |
| 278 frame.bubble_border()->set_arrow(BubbleBorder::BOTTOM_CENTER); | |
| 279 window_bounds = frame.GetUpdatedWindowBounds( | |
| 280 gfx::Rect(100, 900, 50, 50), // |anchor_rect| | |
| 281 gfx::Size(500, 500), // |client_size| | |
| 282 true); // |adjust_if_offscreen| | |
| 283 EXPECT_EQ(BubbleBorder::BOTTOM_CENTER, frame.bubble_border()->arrow()); | |
| 284 EXPECT_EQ(window_bounds.x(), 0); | |
| 285 EXPECT_EQ(window_bounds.x() + | |
| 286 frame.bubble_border()->GetArrowOffset(window_bounds.size()), 125); | |
| 287 | |
| 288 // Test bubble not fitting right screen edge. | |
| 289 frame.bubble_border()->set_arrow(BubbleBorder::TOP_CENTER); | |
| 290 window_bounds = frame.GetUpdatedWindowBounds( | |
| 291 gfx::Rect(900, 100, 50, 50), // |anchor_rect| | |
| 292 gfx::Size(500, 500), // |client_size| | |
| 293 true); // |adjust_if_offscreen| | |
| 294 EXPECT_EQ(BubbleBorder::TOP_CENTER, frame.bubble_border()->arrow()); | |
| 295 EXPECT_EQ(window_bounds.right(), 1000); | |
| 296 EXPECT_EQ(window_bounds.x() + | |
| 297 frame.bubble_border()->GetArrowOffset(window_bounds.size()), 925); | |
| 298 | |
| 299 frame.bubble_border()->set_arrow(BubbleBorder::BOTTOM_CENTER); | |
| 300 window_bounds = frame.GetUpdatedWindowBounds( | |
| 301 gfx::Rect(900, 900, 50, 50), // |anchor_rect| | |
| 302 gfx::Size(500, 500), // |client_size| | |
| 303 true); // |adjust_if_offscreen| | |
| 304 EXPECT_EQ(BubbleBorder::BOTTOM_CENTER, frame.bubble_border()->arrow()); | |
| 305 EXPECT_EQ(window_bounds.right(), 1000); | |
| 306 EXPECT_EQ(window_bounds.x() + | |
| 307 frame.bubble_border()->GetArrowOffset(window_bounds.size()), 925); | |
| 308 | |
| 309 // Test bubble not fitting top screen edge. | |
| 310 frame.bubble_border()->set_arrow(BubbleBorder::LEFT_CENTER); | |
| 311 window_bounds = frame.GetUpdatedWindowBounds( | |
| 312 gfx::Rect(100, 100, 50, 50), // |anchor_rect| | |
| 313 gfx::Size(500, 500), // |client_size| | |
| 314 true); // |adjust_if_offscreen| | |
| 315 EXPECT_EQ(BubbleBorder::LEFT_CENTER, frame.bubble_border()->arrow()); | |
| 316 EXPECT_EQ(window_bounds.y(), 0); | |
| 317 EXPECT_EQ(window_bounds.y() + | |
| 318 frame.bubble_border()->GetArrowOffset(window_bounds.size()), 125); | |
| 319 | |
| 320 frame.bubble_border()->set_arrow(BubbleBorder::RIGHT_CENTER); | |
| 321 window_bounds = frame.GetUpdatedWindowBounds( | |
| 322 gfx::Rect(900, 100, 50, 50), // |anchor_rect| | |
| 323 gfx::Size(500, 500), // |client_size| | |
| 324 true); // |adjust_if_offscreen| | |
| 325 EXPECT_EQ(BubbleBorder::RIGHT_CENTER, frame.bubble_border()->arrow()); | |
| 326 EXPECT_EQ(window_bounds.y(), 0); | |
| 327 EXPECT_EQ(window_bounds.y() + | |
| 328 frame.bubble_border()->GetArrowOffset(window_bounds.size()), 125); | |
| 329 | |
| 330 // Test bubble not fitting bottom screen edge. | |
| 331 frame.bubble_border()->set_arrow(BubbleBorder::LEFT_CENTER); | |
| 332 window_bounds = frame.GetUpdatedWindowBounds( | |
| 333 gfx::Rect(100, 900, 50, 50), // |anchor_rect| | |
| 334 gfx::Size(500, 500), // |client_size| | |
| 335 true); // |adjust_if_offscreen| | |
| 336 EXPECT_EQ(BubbleBorder::LEFT_CENTER, frame.bubble_border()->arrow()); | |
| 337 EXPECT_EQ(window_bounds.bottom(), 1000); | |
| 338 EXPECT_EQ(window_bounds.y() + | |
| 339 frame.bubble_border()->GetArrowOffset(window_bounds.size()), 925); | |
| 340 | |
| 341 frame.bubble_border()->set_arrow(BubbleBorder::RIGHT_CENTER); | |
| 342 window_bounds = frame.GetUpdatedWindowBounds( | |
| 343 gfx::Rect(900, 900, 50, 50), // |anchor_rect| | |
| 344 gfx::Size(500, 500), // |client_size| | |
| 345 true); // |adjust_if_offscreen| | |
| 346 EXPECT_EQ(BubbleBorder::RIGHT_CENTER, frame.bubble_border()->arrow()); | |
| 347 EXPECT_EQ(window_bounds.bottom(), 1000); | |
| 348 EXPECT_EQ(window_bounds.y() + | |
| 349 frame.bubble_border()->GetArrowOffset(window_bounds.size()), 925); | |
| 350 } | |
| 351 | |
| 352 } // namespace views | |
| OLD | NEW |