| 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 "base/basictypes.h" | |
| 6 #include "base/strings/utf_string_conversions.h" | |
| 7 #include "ui/base/ui_base_types.h" | |
| 8 #include "ui/views/controls/button/label_button.h" | |
| 9 #include "ui/views/test/test_views.h" | |
| 10 #include "ui/views/test/views_test_base.h" | |
| 11 #include "ui/views/widget/widget.h" | |
| 12 #include "ui/views/window/dialog_client_view.h" | |
| 13 #include "ui/views/window/dialog_delegate.h" | |
| 14 | |
| 15 namespace views { | |
| 16 | |
| 17 class TestDialogClientView : public DialogClientView { | |
| 18 public: | |
| 19 TestDialogClientView(View* contents_view, | |
| 20 DialogDelegate* dialog_delegate) | |
| 21 : DialogClientView(contents_view), | |
| 22 dialog_(dialog_delegate) {} | |
| 23 virtual ~TestDialogClientView() {} | |
| 24 | |
| 25 // DialogClientView implementation. | |
| 26 virtual DialogDelegate* GetDialogDelegate() const override { return dialog_; } | |
| 27 | |
| 28 View* GetContentsView() { return contents_view(); } | |
| 29 | |
| 30 void CreateExtraViews() { | |
| 31 CreateExtraView(); | |
| 32 CreateFootnoteView(); | |
| 33 } | |
| 34 | |
| 35 private: | |
| 36 DialogDelegate* dialog_; | |
| 37 | |
| 38 DISALLOW_COPY_AND_ASSIGN(TestDialogClientView); | |
| 39 }; | |
| 40 | |
| 41 class DialogClientViewTest : public ViewsTestBase, | |
| 42 public DialogDelegateView { | |
| 43 public: | |
| 44 DialogClientViewTest() | |
| 45 : dialog_buttons_(ui::DIALOG_BUTTON_NONE), | |
| 46 extra_view_(NULL), | |
| 47 footnote_view_(NULL) {} | |
| 48 virtual ~DialogClientViewTest() {} | |
| 49 | |
| 50 // testing::Test implementation. | |
| 51 virtual void SetUp() override { | |
| 52 dialog_buttons_ = ui::DIALOG_BUTTON_NONE; | |
| 53 contents_.reset(new StaticSizedView(gfx::Size(100, 200))); | |
| 54 client_view_.reset(new TestDialogClientView(contents_.get(), this)); | |
| 55 | |
| 56 ViewsTestBase::SetUp(); | |
| 57 } | |
| 58 | |
| 59 // DialogDelegateView implementation. | |
| 60 virtual View* GetContentsView() override { return contents_.get(); } | |
| 61 virtual View* CreateExtraView() override { return extra_view_; } | |
| 62 virtual View* CreateFootnoteView() override { return footnote_view_; } | |
| 63 virtual int GetDialogButtons() const override { return dialog_buttons_; } | |
| 64 | |
| 65 protected: | |
| 66 gfx::Rect GetUpdatedClientBounds() { | |
| 67 client_view_->SizeToPreferredSize(); | |
| 68 client_view_->Layout(); | |
| 69 return client_view_->bounds(); | |
| 70 } | |
| 71 | |
| 72 // Makes sure that the content view is sized correctly. Width must be at least | |
| 73 // the requested amount, but height should always match exactly. | |
| 74 void CheckContentsIsSetToPreferredSize() { | |
| 75 const gfx::Rect client_bounds = GetUpdatedClientBounds(); | |
| 76 const gfx::Size preferred_size = contents_->GetPreferredSize(); | |
| 77 EXPECT_EQ(preferred_size.height(), contents_->bounds().height()); | |
| 78 EXPECT_LE(preferred_size.width(), contents_->bounds().width()); | |
| 79 EXPECT_EQ(contents_->bounds().origin(), client_bounds.origin()); | |
| 80 EXPECT_EQ(contents_->bounds().right(), client_bounds.right()); | |
| 81 } | |
| 82 | |
| 83 // Sets the buttons to show in the dialog and refreshes the dialog. | |
| 84 void SetDialogButtons(int dialog_buttons) { | |
| 85 dialog_buttons_ = dialog_buttons; | |
| 86 client_view_->UpdateDialogButtons(); | |
| 87 } | |
| 88 | |
| 89 // Sets the extra view. | |
| 90 void SetExtraView(View* view) { | |
| 91 DCHECK(!extra_view_); | |
| 92 extra_view_ = view; | |
| 93 client_view_->CreateExtraViews(); | |
| 94 } | |
| 95 | |
| 96 // Sets the footnote view. | |
| 97 void SetFootnoteView(View* view) { | |
| 98 DCHECK(!footnote_view_); | |
| 99 footnote_view_ = view; | |
| 100 client_view_->CreateExtraViews(); | |
| 101 } | |
| 102 | |
| 103 TestDialogClientView* client_view() { return client_view_.get(); } | |
| 104 | |
| 105 private: | |
| 106 // The contents of the dialog. | |
| 107 scoped_ptr<View> contents_; | |
| 108 // The DialogClientView that's being tested. | |
| 109 scoped_ptr<TestDialogClientView> client_view_; | |
| 110 // The bitmask of buttons to show in the dialog. | |
| 111 int dialog_buttons_; | |
| 112 View* extra_view_; // weak | |
| 113 View* footnote_view_; // weak | |
| 114 | |
| 115 DISALLOW_COPY_AND_ASSIGN(DialogClientViewTest); | |
| 116 }; | |
| 117 | |
| 118 TEST_F(DialogClientViewTest, UpdateButtons) { | |
| 119 // This dialog should start with no buttons. | |
| 120 EXPECT_EQ(GetDialogButtons(), ui::DIALOG_BUTTON_NONE); | |
| 121 EXPECT_EQ(NULL, client_view()->ok_button()); | |
| 122 EXPECT_EQ(NULL, client_view()->cancel_button()); | |
| 123 const int height_without_buttons = GetUpdatedClientBounds().height(); | |
| 124 | |
| 125 // Update to use both buttons. | |
| 126 SetDialogButtons(ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL); | |
| 127 EXPECT_TRUE(client_view()->ok_button()->is_default()); | |
| 128 EXPECT_FALSE(client_view()->cancel_button()->is_default()); | |
| 129 const int height_with_buttons = GetUpdatedClientBounds().height(); | |
| 130 EXPECT_GT(height_with_buttons, height_without_buttons); | |
| 131 | |
| 132 // Remove the dialog buttons. | |
| 133 SetDialogButtons(ui::DIALOG_BUTTON_NONE); | |
| 134 EXPECT_EQ(NULL, client_view()->ok_button()); | |
| 135 EXPECT_EQ(NULL, client_view()->cancel_button()); | |
| 136 EXPECT_EQ(GetUpdatedClientBounds().height(), height_without_buttons); | |
| 137 | |
| 138 // Reset with just an ok button. | |
| 139 SetDialogButtons(ui::DIALOG_BUTTON_OK); | |
| 140 EXPECT_TRUE(client_view()->ok_button()->is_default()); | |
| 141 EXPECT_EQ(NULL, client_view()->cancel_button()); | |
| 142 EXPECT_EQ(GetUpdatedClientBounds().height(), height_with_buttons); | |
| 143 | |
| 144 // Reset with just a cancel button. | |
| 145 SetDialogButtons(ui::DIALOG_BUTTON_CANCEL); | |
| 146 EXPECT_EQ(NULL, client_view()->ok_button()); | |
| 147 EXPECT_TRUE(client_view()->cancel_button()->is_default()); | |
| 148 EXPECT_EQ(GetUpdatedClientBounds().height(), height_with_buttons); | |
| 149 } | |
| 150 | |
| 151 TEST_F(DialogClientViewTest, RemoveAndUpdateButtons) { | |
| 152 // Removing buttons from another context should clear the local pointer. | |
| 153 SetDialogButtons(ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL); | |
| 154 delete client_view()->ok_button(); | |
| 155 EXPECT_EQ(NULL, client_view()->ok_button()); | |
| 156 delete client_view()->cancel_button(); | |
| 157 EXPECT_EQ(NULL, client_view()->cancel_button()); | |
| 158 | |
| 159 // Updating should restore the requested buttons properly. | |
| 160 SetDialogButtons(ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL); | |
| 161 EXPECT_TRUE(client_view()->ok_button()->is_default()); | |
| 162 EXPECT_FALSE(client_view()->cancel_button()->is_default()); | |
| 163 } | |
| 164 | |
| 165 // Test that the contents view gets its preferred size in the basic dialog | |
| 166 // configuration. | |
| 167 TEST_F(DialogClientViewTest, ContentsSize) { | |
| 168 CheckContentsIsSetToPreferredSize(); | |
| 169 EXPECT_EQ(GetContentsView()->bounds().bottom(), | |
| 170 client_view()->bounds().bottom()); | |
| 171 } | |
| 172 | |
| 173 // Test the effect of the button strip on layout. | |
| 174 TEST_F(DialogClientViewTest, LayoutWithButtons) { | |
| 175 SetDialogButtons(ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL); | |
| 176 CheckContentsIsSetToPreferredSize(); | |
| 177 EXPECT_LT(GetContentsView()->bounds().bottom(), | |
| 178 client_view()->bounds().bottom()); | |
| 179 gfx::Size no_extra_view_size = client_view()->bounds().size(); | |
| 180 | |
| 181 View* extra_view = new StaticSizedView(gfx::Size(200, 200)); | |
| 182 SetExtraView(extra_view); | |
| 183 CheckContentsIsSetToPreferredSize(); | |
| 184 EXPECT_GT(client_view()->bounds().height(), no_extra_view_size.height()); | |
| 185 int width_of_extra_view = extra_view->bounds().width(); | |
| 186 | |
| 187 // Visibility of extra view is respected. | |
| 188 extra_view->SetVisible(false); | |
| 189 CheckContentsIsSetToPreferredSize(); | |
| 190 EXPECT_EQ(no_extra_view_size.height(), client_view()->bounds().height()); | |
| 191 EXPECT_EQ(no_extra_view_size.width(), client_view()->bounds().width()); | |
| 192 | |
| 193 // Try with a reduced-size dialog. | |
| 194 extra_view->SetVisible(true); | |
| 195 client_view()->SetBoundsRect(gfx::Rect(gfx::Point(0, 0), no_extra_view_size)); | |
| 196 client_view()->Layout(); | |
| 197 DCHECK_GT(width_of_extra_view, extra_view->bounds().width()); | |
| 198 } | |
| 199 | |
| 200 // Test the effect of the footnote view on layout. | |
| 201 TEST_F(DialogClientViewTest, LayoutWithFootnote) { | |
| 202 CheckContentsIsSetToPreferredSize(); | |
| 203 gfx::Size no_footnote_size = client_view()->bounds().size(); | |
| 204 | |
| 205 View* footnote_view = new StaticSizedView(gfx::Size(200, 200)); | |
| 206 SetFootnoteView(footnote_view); | |
| 207 CheckContentsIsSetToPreferredSize(); | |
| 208 EXPECT_GT(client_view()->bounds().height(), no_footnote_size.height()); | |
| 209 EXPECT_EQ(200, footnote_view->bounds().height()); | |
| 210 gfx::Size with_footnote_size = client_view()->bounds().size(); | |
| 211 EXPECT_EQ(with_footnote_size.width(), footnote_view->bounds().width()); | |
| 212 | |
| 213 SetDialogButtons(ui::DIALOG_BUTTON_CANCEL); | |
| 214 CheckContentsIsSetToPreferredSize(); | |
| 215 EXPECT_LE(with_footnote_size.height(), client_view()->bounds().height()); | |
| 216 EXPECT_LE(with_footnote_size.width(), client_view()->bounds().width()); | |
| 217 gfx::Size with_footnote_and_button_size = client_view()->bounds().size(); | |
| 218 | |
| 219 SetDialogButtons(ui::DIALOG_BUTTON_NONE); | |
| 220 footnote_view->SetVisible(false); | |
| 221 CheckContentsIsSetToPreferredSize(); | |
| 222 EXPECT_EQ(no_footnote_size.height(), client_view()->bounds().height()); | |
| 223 EXPECT_EQ(no_footnote_size.width(), client_view()->bounds().width()); | |
| 224 } | |
| 225 | |
| 226 // Test that GetHeightForWidth is respected for the footnote view. | |
| 227 TEST_F(DialogClientViewTest, LayoutWithFootnoteHeightForWidth) { | |
| 228 CheckContentsIsSetToPreferredSize(); | |
| 229 gfx::Size no_footnote_size = client_view()->bounds().size(); | |
| 230 | |
| 231 View* footnote_view = new ProportionallySizedView(3); | |
| 232 SetFootnoteView(footnote_view); | |
| 233 CheckContentsIsSetToPreferredSize(); | |
| 234 EXPECT_GT(client_view()->bounds().height(), no_footnote_size.height()); | |
| 235 EXPECT_EQ(footnote_view->bounds().width() * 3, | |
| 236 footnote_view->bounds().height()); | |
| 237 } | |
| 238 | |
| 239 // Test that the DialogClientView's FocusManager is properly updated when the | |
| 240 // DialogClientView belongs to a non top level widget and the widget is | |
| 241 // reparented. The DialogClientView belongs to a non top level widget in the | |
| 242 // case of constrained windows. The constrained window's widget is reparented | |
| 243 // when a browser tab is dragged to a different browser window. | |
| 244 TEST_F(DialogClientViewTest, FocusManager) { | |
| 245 scoped_ptr<Widget> toplevel1(new Widget); | |
| 246 Widget::InitParams toplevel1_params = | |
| 247 CreateParams(Widget::InitParams::TYPE_WINDOW); | |
| 248 toplevel1_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | |
| 249 toplevel1->Init(toplevel1_params); | |
| 250 | |
| 251 scoped_ptr<Widget> toplevel2(new Widget); | |
| 252 Widget::InitParams toplevel2_params = | |
| 253 CreateParams(Widget::InitParams::TYPE_WINDOW); | |
| 254 toplevel2_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | |
| 255 toplevel2->Init(toplevel2_params); | |
| 256 | |
| 257 Widget* dialog = new Widget; | |
| 258 Widget::InitParams dialog_params = | |
| 259 CreateParams(Widget::InitParams::TYPE_WINDOW); | |
| 260 dialog_params.child = true; | |
| 261 dialog_params.delegate = new DialogDelegateView(); | |
| 262 dialog_params.parent = toplevel1->GetNativeView(); | |
| 263 dialog->Init(dialog_params); | |
| 264 | |
| 265 // Test that the FocusManager has been properly set when the DialogClientView | |
| 266 // was parented to |dialog|. | |
| 267 DialogClientView* client_view = | |
| 268 static_cast<DialogClientView*>(dialog->client_view()); | |
| 269 EXPECT_EQ(toplevel1->GetFocusManager(), client_view->focus_manager_); | |
| 270 | |
| 271 // Test that the FocusManager is properly updated when the DialogClientView's | |
| 272 // top level widget is changed. | |
| 273 Widget::ReparentNativeView(dialog->GetNativeView(), NULL); | |
| 274 EXPECT_EQ(NULL, client_view->focus_manager_); | |
| 275 Widget::ReparentNativeView(dialog->GetNativeView(), | |
| 276 toplevel2->GetNativeView()); | |
| 277 EXPECT_EQ(toplevel2->GetFocusManager(), client_view->focus_manager_); | |
| 278 Widget::ReparentNativeView(dialog->GetNativeView(), | |
| 279 toplevel1->GetNativeView()); | |
| 280 EXPECT_NE(toplevel1->GetFocusManager(), toplevel2->GetFocusManager()); | |
| 281 EXPECT_EQ(toplevel1->GetFocusManager(), client_view->focus_manager_); | |
| 282 | |
| 283 // Test that the FocusManager is properly cleared when the DialogClientView is | |
| 284 // removed from |dialog| during the widget's destruction. | |
| 285 client_view->set_owned_by_client(); | |
| 286 scoped_ptr<DialogClientView> owned_client_view(client_view); | |
| 287 toplevel1->CloseNow(); | |
| 288 toplevel2->CloseNow(); | |
| 289 EXPECT_EQ(NULL, owned_client_view->focus_manager_); | |
| 290 } | |
| 291 | |
| 292 } // namespace views | |
| OLD | NEW |