| 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 "ui/views/bubble/bubble_delegate.h" | 5 #include "ui/views/bubble/bubble_delegate.h" |
| 6 #include "ui/views/bubble/bubble_frame_view.h" | 6 #include "ui/views/bubble/bubble_frame_view.h" |
| 7 #include "ui/views/test/views_test_base.h" | 7 #include "ui/views/test/views_test_base.h" |
| 8 #include "ui/views/widget/widget.h" | 8 #include "ui/views/widget/widget.h" |
| 9 | 9 |
| 10 namespace views { | 10 namespace views { |
| 11 | 11 |
| 12 namespace { |
| 13 |
| 14 // A Widget observer class used in the tests below to observe bubbles closing. |
| 15 class TestWidgetObserver : public WidgetObserver { |
| 16 public: |
| 17 explicit TestWidgetObserver(Widget* widget); |
| 18 virtual ~TestWidgetObserver(); |
| 19 |
| 20 // WidgetObserver overrides: |
| 21 virtual void OnWidgetClosing(Widget* widget) OVERRIDE; |
| 22 |
| 23 bool widget_closed() const { return widget_ == NULL; } |
| 24 |
| 25 private: |
| 26 Widget* widget_; |
| 27 }; |
| 28 |
| 29 TestWidgetObserver::TestWidgetObserver(Widget* widget) |
| 30 : widget_(widget) { |
| 31 widget_->AddObserver(this); |
| 32 } |
| 33 |
| 34 TestWidgetObserver::~TestWidgetObserver() { |
| 35 if (widget_) |
| 36 widget_->RemoveObserver(this); |
| 37 } |
| 38 |
| 39 void TestWidgetObserver::OnWidgetClosing(Widget* widget) { |
| 40 DCHECK_EQ(widget_, widget); |
| 41 widget_ = NULL; |
| 42 } |
| 43 |
| 44 } // namespace |
| 45 |
| 12 typedef ViewsTestBase BubbleDelegateTest; | 46 typedef ViewsTestBase BubbleDelegateTest; |
| 13 | 47 |
| 14 TEST_F(BubbleDelegateTest, CreateDelegate) { | 48 TEST_F(BubbleDelegateTest, CreateDelegate) { |
| 15 BubbleDelegateView* bubble_delegate = | 49 BubbleDelegateView* bubble_delegate = |
| 16 new BubbleDelegateView(NULL, BubbleBorder::NONE); | 50 new BubbleDelegateView(NULL, BubbleBorder::NONE); |
| 17 bubble_delegate->set_color(SK_ColorGREEN); | 51 bubble_delegate->set_color(SK_ColorGREEN); |
| 18 Widget* bubble_widget( | 52 Widget* bubble_widget( |
| 19 BubbleDelegateView::CreateBubble(bubble_delegate)); | 53 BubbleDelegateView::CreateBubble(bubble_delegate)); |
| 20 EXPECT_EQ(bubble_delegate, bubble_widget->widget_delegate()); | 54 EXPECT_EQ(bubble_delegate, bubble_widget->widget_delegate()); |
| 21 EXPECT_EQ(bubble_widget, bubble_delegate->GetWidget()); | 55 EXPECT_EQ(bubble_widget, bubble_delegate->GetWidget()); |
| 56 TestWidgetObserver bubble_observer(bubble_widget); |
| 57 EXPECT_FALSE(bubble_observer.widget_closed()); |
| 22 | 58 |
| 23 BubbleBorder* border = | 59 BubbleBorder* border = |
| 24 bubble_delegate->GetBubbleFrameView()->bubble_border(); | 60 bubble_delegate->GetBubbleFrameView()->bubble_border(); |
| 25 EXPECT_EQ(bubble_delegate->arrow_location(), border->arrow_location()); | 61 EXPECT_EQ(bubble_delegate->arrow_location(), border->arrow_location()); |
| 26 EXPECT_EQ(bubble_delegate->color(), border->background_color()); | 62 EXPECT_EQ(bubble_delegate->color(), border->background_color()); |
| 27 | 63 |
| 28 bubble_widget->CloseNow(); | 64 bubble_widget->CloseNow(); |
| 29 RunPendingMessages(); | 65 RunPendingMessages(); |
| 66 EXPECT_TRUE(bubble_observer.widget_closed()); |
| 67 } |
| 68 |
| 69 TEST_F(BubbleDelegateTest, CloseAnchorWidget) { |
| 70 // Create the anchor widget. |
| 71 Widget::InitParams params(Widget::InitParams::TYPE_WINDOW); |
| 72 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
| 73 scoped_ptr<Widget> anchor_widget(new Widget); |
| 74 anchor_widget->Init(params); |
| 75 anchor_widget->Show(); |
| 76 |
| 77 BubbleDelegateView* bubble_delegate = new BubbleDelegateView( |
| 78 anchor_widget->GetContentsView(), BubbleBorder::NONE); |
| 79 // Preventing close on deactivate should not prevent closing with the anchor. |
| 80 bubble_delegate->set_close_on_deactivate(false); |
| 81 Widget* bubble_widget = BubbleDelegateView::CreateBubble(bubble_delegate); |
| 82 EXPECT_EQ(bubble_delegate, bubble_widget->widget_delegate()); |
| 83 EXPECT_EQ(bubble_widget, bubble_delegate->GetWidget()); |
| 84 EXPECT_EQ(anchor_widget.get(), bubble_delegate->anchor_widget()); |
| 85 TestWidgetObserver bubble_observer(bubble_widget); |
| 86 EXPECT_FALSE(bubble_observer.widget_closed()); |
| 87 |
| 88 bubble_widget->Show(); |
| 89 RunPendingMessages(); |
| 90 EXPECT_EQ(anchor_widget.get(), bubble_delegate->anchor_widget()); |
| 91 EXPECT_FALSE(bubble_observer.widget_closed()); |
| 92 |
| 93 // Ensure that closing the anchor widget also closes the bubble itself. |
| 94 anchor_widget->CloseNow(); |
| 95 RunPendingMessages(); |
| 96 EXPECT_TRUE(bubble_observer.widget_closed()); |
| 30 } | 97 } |
| 31 | 98 |
| 32 TEST_F(BubbleDelegateTest, ResetAnchorWidget) { | 99 TEST_F(BubbleDelegateTest, ResetAnchorWidget) { |
| 33 // Create the anchor widget first. | 100 // Create the anchor and parent widgets. |
| 34 Widget* widget = new Widget; | |
| 35 View* contents = new View; | |
| 36 | |
| 37 Widget::InitParams params(Widget::InitParams::TYPE_WINDOW); | 101 Widget::InitParams params(Widget::InitParams::TYPE_WINDOW); |
| 38 widget->Init(params); | 102 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
| 39 widget->SetContentsView(contents); | 103 scoped_ptr<Widget> anchor_widget(new Widget); |
| 40 widget->Show(); | 104 anchor_widget->Init(params); |
| 41 | 105 anchor_widget->Show(); |
| 42 Widget* parent = new Widget; | 106 scoped_ptr<Widget> parent_widget(new Widget); |
| 43 parent->Init(params); | 107 parent_widget->Init(params); |
| 44 parent->SetContentsView(new View); | 108 parent_widget->Show(); |
| 45 parent->Show(); | |
| 46 | 109 |
| 47 // Make sure the bubble widget is parented to a widget other than the anchor | 110 // Make sure the bubble widget is parented to a widget other than the anchor |
| 48 // widget so that closing the anchor widget does not close the bubble widget. | 111 // widget so that closing the anchor widget does not close the bubble widget. |
| 49 BubbleDelegateView* bubble_delegate = | 112 BubbleDelegateView* bubble_delegate = new BubbleDelegateView( |
| 50 new BubbleDelegateView(contents, BubbleBorder::NONE); | 113 anchor_widget->GetContentsView(), BubbleBorder::NONE); |
| 51 bubble_delegate->set_parent_window(parent->GetNativeView()); | 114 bubble_delegate->set_parent_window(parent_widget->GetNativeView()); |
| 52 bubble_delegate->set_color(SK_ColorGREEN); | 115 // Preventing close on deactivate should not prevent closing with the parent. |
| 53 Widget* bubble_widget( | 116 bubble_delegate->set_close_on_deactivate(false); |
| 54 BubbleDelegateView::CreateBubble(bubble_delegate)); | 117 Widget* bubble_widget = BubbleDelegateView::CreateBubble(bubble_delegate); |
| 55 EXPECT_EQ(bubble_delegate, bubble_widget->widget_delegate()); | 118 EXPECT_EQ(bubble_delegate, bubble_widget->widget_delegate()); |
| 56 EXPECT_EQ(bubble_widget, bubble_delegate->GetWidget()); | 119 EXPECT_EQ(bubble_widget, bubble_delegate->GetWidget()); |
| 57 EXPECT_EQ(widget, bubble_delegate->anchor_widget()); | 120 EXPECT_EQ(anchor_widget.get(), bubble_delegate->anchor_widget()); |
| 121 TestWidgetObserver bubble_observer(bubble_widget); |
| 122 EXPECT_FALSE(bubble_observer.widget_closed()); |
| 58 | 123 |
| 124 // Showing and hiding the bubble widget should have no effect on its anchor. |
| 59 bubble_widget->Show(); | 125 bubble_widget->Show(); |
| 60 RunPendingMessages(); | 126 RunPendingMessages(); |
| 61 EXPECT_EQ(widget, bubble_delegate->anchor_widget()); | 127 EXPECT_EQ(anchor_widget.get(), bubble_delegate->anchor_widget()); |
| 62 | |
| 63 bubble_widget->Hide(); | 128 bubble_widget->Hide(); |
| 64 RunPendingMessages(); | 129 RunPendingMessages(); |
| 65 EXPECT_EQ(widget, bubble_delegate->anchor_widget()); | 130 EXPECT_EQ(anchor_widget.get(), bubble_delegate->anchor_widget()); |
| 66 | 131 |
| 67 // Closing the anchor widget should unset the reference to the anchor widget | 132 // Ensure that closing the anchor widget clears the bubble's reference to that |
| 68 // for the bubble. | 133 // anchor widget, but the bubble itself does not close. |
| 69 widget->CloseNow(); | 134 anchor_widget->CloseNow(); |
| 70 RunPendingMessages(); | 135 RunPendingMessages(); |
| 71 EXPECT_NE(bubble_delegate->anchor_widget(), widget); | 136 EXPECT_NE(anchor_widget.get(), bubble_delegate->anchor_widget()); |
| 137 EXPECT_FALSE(bubble_observer.widget_closed()); |
| 72 | 138 |
| 73 bubble_widget->CloseNow(); | 139 // Ensure that closing the parent widget also closes the bubble itself. |
| 74 parent->CloseNow(); | 140 parent_widget->CloseNow(); |
| 75 RunPendingMessages(); | 141 RunPendingMessages(); |
| 142 EXPECT_TRUE(bubble_observer.widget_closed()); |
| 76 } | 143 } |
| 77 | 144 |
| 78 } // namespace views | 145 } // namespace views |
| OLD | NEW |