OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 "ui/views/bubble/bubble_dialog_delegate.h" | 5 #include "ui/views/bubble/bubble_dialog_delegate.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include "base/i18n/rtl.h" | 9 #include "base/i18n/rtl.h" |
10 #include "base/macros.h" | 10 #include "base/macros.h" |
| 11 #include "base/strings/utf_string_conversions.h" |
11 #include "ui/base/hit_test.h" | 12 #include "ui/base/hit_test.h" |
12 #include "ui/events/event_utils.h" | 13 #include "ui/events/event_utils.h" |
13 #include "ui/views/bubble/bubble_frame_view.h" | 14 #include "ui/views/bubble/bubble_frame_view.h" |
14 #include "ui/views/controls/button/label_button.h" | 15 #include "ui/views/controls/button/label_button.h" |
| 16 #include "ui/views/test/test_views.h" |
15 #include "ui/views/test/test_widget_observer.h" | 17 #include "ui/views/test/test_widget_observer.h" |
16 #include "ui/views/test/views_test_base.h" | 18 #include "ui/views/test/views_test_base.h" |
17 #include "ui/views/widget/widget.h" | 19 #include "ui/views/widget/widget.h" |
18 #include "ui/views/widget/widget_observer.h" | 20 #include "ui/views/widget/widget_observer.h" |
19 | 21 |
20 namespace views { | 22 namespace views { |
21 | 23 |
22 namespace { | 24 namespace { |
23 | 25 |
24 class TestBubbleDialogDelegateView : public BubbleDialogDelegateView { | 26 class TestBubbleDialogDelegateView : public BubbleDialogDelegateView { |
25 public: | 27 public: |
26 TestBubbleDialogDelegateView(View* anchor_view) | 28 TestBubbleDialogDelegateView(View* anchor_view) |
27 : BubbleDialogDelegateView(anchor_view, BubbleBorder::TOP_LEFT), | 29 : BubbleDialogDelegateView(anchor_view, BubbleBorder::TOP_LEFT), |
28 view_(new View()) { | 30 view_(new View()), |
| 31 title_view_(nullptr), |
| 32 should_show_close_button_(false) { |
29 view_->SetFocusBehavior(FocusBehavior::ALWAYS); | 33 view_->SetFocusBehavior(FocusBehavior::ALWAYS); |
30 AddChildView(view_); | 34 AddChildView(view_); |
31 } | 35 } |
32 ~TestBubbleDialogDelegateView() override {} | 36 ~TestBubbleDialogDelegateView() override {} |
33 | 37 |
34 // BubbleDialogDelegateView overrides: | 38 // BubbleDialogDelegateView overrides: |
35 View* GetInitiallyFocusedView() override { return view_; } | 39 View* GetInitiallyFocusedView() override { return view_; } |
36 gfx::Size CalculatePreferredSize() const override { | 40 gfx::Size CalculatePreferredSize() const override { |
37 return gfx::Size(200, 200); | 41 return gfx::Size(200, 200); |
38 } | 42 } |
| 43 void AddedToWidget() override { |
| 44 if (title_view_) |
| 45 GetBubbleFrameView()->SetTitleView(std::move(title_view_)); |
| 46 } |
| 47 |
| 48 base::string16 GetWindowTitle() const override { |
| 49 return base::ASCIIToUTF16("TITLE TITLE TITLE"); |
| 50 } |
| 51 |
| 52 bool ShouldShowCloseButton() const override { |
| 53 return should_show_close_button_; |
| 54 } |
| 55 |
| 56 void set_title_view(View* title_view) { title_view_.reset(title_view); } |
| 57 void show_close_button() { should_show_close_button_ = true; } |
39 | 58 |
40 using BubbleDialogDelegateView::SetAnchorRect; | 59 using BubbleDialogDelegateView::SetAnchorRect; |
41 using BubbleDialogDelegateView::GetBubbleFrameView; | 60 using BubbleDialogDelegateView::GetBubbleFrameView; |
42 | 61 |
43 private: | 62 private: |
44 View* view_; | 63 View* view_; |
| 64 std::unique_ptr<View> title_view_; |
| 65 bool should_show_close_button_; |
45 | 66 |
46 DISALLOW_COPY_AND_ASSIGN(TestBubbleDialogDelegateView); | 67 DISALLOW_COPY_AND_ASSIGN(TestBubbleDialogDelegateView); |
47 }; | 68 }; |
48 | 69 |
49 class BubbleDialogDelegateTest : public ViewsTestBase { | 70 class BubbleDialogDelegateTest : public ViewsTestBase { |
50 public: | 71 public: |
51 BubbleDialogDelegateTest() {} | 72 BubbleDialogDelegateTest() {} |
52 ~BubbleDialogDelegateTest() override {} | 73 ~BubbleDialogDelegateTest() override {} |
53 | 74 |
54 // Creates and shows a test widget that owns its native widget. | 75 // Creates and shows a test widget that owns its native widget. |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
244 TestBubbleDialogDelegateView* bubble_delegate = | 265 TestBubbleDialogDelegateView* bubble_delegate = |
245 new TestBubbleDialogDelegateView(anchor_widget->GetContentsView()); | 266 new TestBubbleDialogDelegateView(anchor_widget->GetContentsView()); |
246 BubbleDialogDelegateView::CreateBubble(bubble_delegate); | 267 BubbleDialogDelegateView::CreateBubble(bubble_delegate); |
247 BubbleFrameView* frame = bubble_delegate->GetBubbleFrameView(); | 268 BubbleFrameView* frame = bubble_delegate->GetBubbleFrameView(); |
248 const int border = frame->bubble_border()->GetBorderThickness(); | 269 const int border = frame->bubble_border()->GetBorderThickness(); |
249 | 270 |
250 struct { | 271 struct { |
251 const int point; | 272 const int point; |
252 const int hit; | 273 const int hit; |
253 } cases[] = { | 274 } cases[] = { |
254 {border, HTNOWHERE}, {border + 50, HTCLIENT}, {1000, HTNOWHERE}, | 275 {border, HTNOWHERE}, {border + 60, HTCLIENT}, {1000, HTNOWHERE}, |
255 }; | 276 }; |
256 | 277 |
257 for (size_t i = 0; i < arraysize(cases); ++i) { | 278 for (size_t i = 0; i < arraysize(cases); ++i) { |
258 gfx::Point point(cases[i].point, cases[i].point); | 279 gfx::Point point(cases[i].point, cases[i].point); |
259 EXPECT_EQ(cases[i].hit, frame->NonClientHitTest(point)) | 280 EXPECT_EQ(cases[i].hit, frame->NonClientHitTest(point)) |
260 << " with border: " << border << ", at point " << cases[i].point; | 281 << " with border: " << border << ", at point " << cases[i].point; |
261 } | 282 } |
262 } | 283 } |
263 | 284 |
264 TEST_F(BubbleDialogDelegateTest, VisibleWhenAnchorWidgetBoundsChanged) { | 285 TEST_F(BubbleDialogDelegateTest, VisibleWhenAnchorWidgetBoundsChanged) { |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
326 Button* close_button = frame_view->close_; | 347 Button* close_button = frame_view->close_; |
327 ASSERT_TRUE(close_button); | 348 ASSERT_TRUE(close_button); |
328 frame_view->ButtonPressed( | 349 frame_view->ButtonPressed( |
329 close_button, | 350 close_button, |
330 ui::MouseEvent(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(), | 351 ui::MouseEvent(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(), |
331 ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE)); | 352 ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE)); |
332 EXPECT_TRUE(bubble_widget->IsClosed()); | 353 EXPECT_TRUE(bubble_widget->IsClosed()); |
333 } | 354 } |
334 } | 355 } |
335 | 356 |
| 357 TEST_F(BubbleDialogDelegateTest, CustomTitle) { |
| 358 std::unique_ptr<Widget> anchor_widget(CreateTestWidget()); |
| 359 TestBubbleDialogDelegateView* bubble_delegate = |
| 360 new TestBubbleDialogDelegateView(anchor_widget->GetContentsView()); |
| 361 constexpr int kTitlePreferredHeight = 20; |
| 362 View* title_view = new StaticSizedView(gfx::Size(10, kTitlePreferredHeight)); |
| 363 bubble_delegate->set_title_view(title_view); |
| 364 Widget* bubble_widget = |
| 365 BubbleDialogDelegateView::CreateBubble(bubble_delegate); |
| 366 bubble_widget->Show(); |
| 367 |
| 368 BubbleFrameView* bubble_frame = static_cast<BubbleFrameView*>( |
| 369 bubble_widget->non_client_view()->frame_view()); |
| 370 EXPECT_EQ(title_view, bubble_frame->title()); |
| 371 EXPECT_EQ(bubble_frame, title_view->parent()); |
| 372 // Title takes up the whole bubble width when there's no icon or close button. |
| 373 EXPECT_EQ(bubble_delegate->width(), title_view->size().width()); |
| 374 EXPECT_EQ(kTitlePreferredHeight, title_view->size().height()); |
| 375 |
| 376 bubble_delegate->show_close_button(); |
| 377 bubble_frame->ResetWindowControls(); |
| 378 bubble_frame->Layout(); |
| 379 |
| 380 Button* close_button = bubble_frame->GetCloseButtonForTest(); |
| 381 // Title moves over for the close button. |
| 382 EXPECT_EQ(close_button->x() - LayoutProvider::Get()->GetDistanceMetric( |
| 383 DISTANCE_CLOSE_BUTTON_MARGIN), |
| 384 title_view->bounds().right()); |
| 385 } |
| 386 |
336 } // namespace views | 387 } // namespace views |
OLD | NEW |