Index: ui/views/window/dialog_client_view_unittest.cc |
diff --git a/ui/views/window/dialog_client_view_unittest.cc b/ui/views/window/dialog_client_view_unittest.cc |
index e4d7eebb2024cce4e9b19a208b4c48fe5633a059..a8d3d8d79c222a876312009c96f65ee9328bfbb9 100644 |
--- a/ui/views/window/dialog_client_view_unittest.cc |
+++ b/ui/views/window/dialog_client_view_unittest.cc |
@@ -7,6 +7,7 @@ |
#include "base/macros.h" |
#include "base/strings/utf_string_conversions.h" |
#include "build/build_config.h" |
+#include "ui/base/test/material_design_controller_test_api.h" |
#include "ui/base/ui_base_types.h" |
#include "ui/views/controls/button/label_button.h" |
#include "ui/views/style/platform_style.h" |
@@ -43,6 +44,9 @@ class DialogClientViewTest : public test::WidgetTest, |
} |
// DialogDelegateView: |
+ gfx::Size GetPreferredSize() const override { return preferred_size_; } |
+ gfx::Size GetMinimumSize() const override { return min_size_; } |
+ gfx::Size GetMaximumSize() const override { return max_size_; } |
ClientView* CreateClientView(Widget* widget) override { |
client_view_ = new DialogClientView(widget, this); |
return client_view_; |
@@ -63,6 +67,11 @@ class DialogClientViewTest : public test::WidgetTest, |
} |
int GetDialogButtons() const override { return dialog_buttons_; } |
+ base::string16 GetDialogButtonLabel(ui::DialogButton button) const override { |
+ return button == ui::DIALOG_BUTTON_CANCEL && !cancel_label_.empty() |
+ ? cancel_label_ |
+ : DialogDelegate::GetDialogButtonLabel(button); |
+ } |
protected: |
gfx::Rect GetUpdatedClientBounds() { |
@@ -102,7 +111,15 @@ class DialogClientViewTest : public test::WidgetTest, |
void SetExtraViewPadding(int padding) { |
DCHECK(!extra_view_padding_); |
extra_view_padding_.reset(new int(padding)); |
- client_view_->Layout(); |
+ client_view_->UpdateDialogButtons(); |
+ } |
+ |
+ void SetSizeConstraints(const gfx::Size& min_size, |
+ const gfx::Size& preferred_size, |
+ const gfx::Size& max_size) { |
+ min_size_ = min_size; |
+ preferred_size_ = preferred_size; |
+ max_size_ = max_size; |
} |
View* FocusableViewAfter(View* view) { |
@@ -112,6 +129,12 @@ class DialogClientViewTest : public test::WidgetTest, |
dont_loop); |
} |
+ // Set a longer than normal Cancel label so that the minimum button width is |
+ // exceeded. |
+ void SetLongCancelLabel() { |
+ cancel_label_ = base::ASCIIToUTF16("Cancel Cancel Cancel"); |
+ } |
+ |
DialogClientView* client_view() { return client_view_; } |
private: |
@@ -129,6 +152,12 @@ class DialogClientViewTest : public test::WidgetTest, |
std::unique_ptr<int> extra_view_padding_; |
+ gfx::Size preferred_size_; |
+ gfx::Size min_size_; |
+ gfx::Size max_size_; |
+ |
+ base::string16 cancel_label_; // If set, the label for the Cancel button. |
+ |
DISALLOW_COPY_AND_ASSIGN(DialogClientViewTest); |
}; |
@@ -188,24 +217,27 @@ TEST_F(DialogClientViewTest, SetupFocusChain) { |
const bool kIsOkButtonOnLeftSide = false; |
#endif |
+ GetContentsView()->SetFocusBehavior(View::FocusBehavior::ALWAYS); |
// Initially the dialog client view only contains the content view. |
- EXPECT_EQ(nullptr, GetContentsView()->GetNextFocusableView()); |
+ EXPECT_EQ(GetContentsView(), FocusableViewAfter(GetContentsView())); |
// Add OK and cancel buttons. |
SetDialogButtons(ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL); |
if (kIsOkButtonOnLeftSide) { |
EXPECT_EQ(client_view()->ok_button(), |
- GetContentsView()->GetNextFocusableView()); |
+ FocusableViewAfter(GetContentsView())); |
EXPECT_EQ(client_view()->cancel_button(), |
- client_view()->ok_button()->GetNextFocusableView()); |
- EXPECT_EQ(nullptr, client_view()->cancel_button()->GetNextFocusableView()); |
+ FocusableViewAfter(client_view()->ok_button())); |
+ EXPECT_EQ(GetContentsView(), |
+ FocusableViewAfter(client_view()->cancel_button())); |
} else { |
EXPECT_EQ(client_view()->cancel_button(), |
- GetContentsView()->GetNextFocusableView()); |
+ FocusableViewAfter(GetContentsView())); |
EXPECT_EQ(client_view()->ok_button(), |
- client_view()->cancel_button()->GetNextFocusableView()); |
- EXPECT_EQ(nullptr, client_view()->ok_button()->GetNextFocusableView()); |
+ FocusableViewAfter(client_view()->cancel_button())); |
+ EXPECT_EQ(GetContentsView(), |
+ FocusableViewAfter(client_view()->ok_button())); |
} |
// Add extra view and remove OK button. |
@@ -214,14 +246,15 @@ TEST_F(DialogClientViewTest, SetupFocusChain) { |
SetExtraView(extra_view); |
SetDialogButtons(ui::DIALOG_BUTTON_CANCEL); |
- EXPECT_EQ(extra_view, GetContentsView()->GetNextFocusableView()); |
- EXPECT_EQ(client_view()->cancel_button(), extra_view->GetNextFocusableView()); |
- EXPECT_EQ(nullptr, client_view()->cancel_button()->GetNextFocusableView()); |
+ EXPECT_EQ(extra_view, FocusableViewAfter(GetContentsView())); |
+ EXPECT_EQ(client_view()->cancel_button(), FocusableViewAfter(extra_view)); |
+ EXPECT_EQ(GetContentsView(), FocusableViewAfter(client_view())); |
// Add a dummy view to the contents view. Consult the FocusManager for the |
// traversal order since it now spans different levels of the view hierarchy. |
View* dummy_view = new StaticSizedView(gfx::Size(200, 200)); |
dummy_view->SetFocusBehavior(View::FocusBehavior::ALWAYS); |
+ GetContentsView()->SetFocusBehavior(View::FocusBehavior::NEVER); |
GetContentsView()->AddChildView(dummy_view); |
EXPECT_EQ(dummy_view, FocusableViewAfter(client_view()->cancel_button())); |
EXPECT_EQ(extra_view, FocusableViewAfter(dummy_view)); |
@@ -248,31 +281,128 @@ TEST_F(DialogClientViewTest, LayoutWithButtons) { |
EXPECT_LT(GetContentsView()->bounds().bottom(), |
client_view()->bounds().bottom()); |
- gfx::Size no_extra_view_size = client_view()->bounds().size(); |
+ const gfx::Size no_extra_view_size = client_view()->bounds().size(); |
View* extra_view = new StaticSizedView(gfx::Size(200, 200)); |
SetExtraView(extra_view); |
CheckContentsIsSetToPreferredSize(); |
EXPECT_GT(client_view()->bounds().height(), no_extra_view_size.height()); |
- int width_of_dialog = client_view()->bounds().width(); |
- int width_of_extra_view = extra_view->bounds().width(); |
+ const int width_of_dialog_small_padding = client_view()->width(); |
// Try with an adjusted padding for the extra view. |
SetExtraViewPadding(250); |
CheckContentsIsSetToPreferredSize(); |
- EXPECT_GT(client_view()->bounds().width(), width_of_dialog); |
+ EXPECT_GT(client_view()->bounds().width(), width_of_dialog_small_padding); |
- // Visibility of extra view is respected. |
+ const gfx::Size with_extra_view_size = client_view()->size(); |
+ EXPECT_NE(no_extra_view_size, with_extra_view_size); |
+ |
+ // Hiding the extra view removes it as well as the extra padding. |
extra_view->SetVisible(false); |
CheckContentsIsSetToPreferredSize(); |
- EXPECT_EQ(no_extra_view_size.height(), client_view()->bounds().height()); |
- EXPECT_EQ(no_extra_view_size.width(), client_view()->bounds().width()); |
+ EXPECT_EQ(no_extra_view_size, client_view()->size()); |
- // Try with a reduced-size dialog. |
+ // Making it visible again adds it all back. |
extra_view->SetVisible(true); |
- client_view()->SetBoundsRect(gfx::Rect(gfx::Point(0, 0), no_extra_view_size)); |
- client_view()->Layout(); |
- EXPECT_GT(width_of_extra_view, extra_view->bounds().width()); |
+ CheckContentsIsSetToPreferredSize(); |
+ EXPECT_EQ(with_extra_view_size, client_view()->size()); |
+ |
+ // Leave |extra_view| hidden. It should still have a parent, to ensure it is |
+ // owned by a View hierarchy and gets deleted. |
+ extra_view->SetVisible(false); |
+ EXPECT_TRUE(extra_view->parent()); |
+} |
+ |
+// Ensure the minimum, maximum and preferred sizes of the contents view are |
+// respected by the client view, and that the client view includes the button |
+// row in its minimum and preferred size calculations. |
+TEST_F(DialogClientViewTest, MinMaxPreferredSize) { |
+ SetDialogButtons(ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL); |
+ const gfx::Size buttons_size = client_view()->GetPreferredSize(); |
+ EXPECT_FALSE(buttons_size.IsEmpty()); |
+ |
+ // When the contents view has no preference, just fit the buttons. The |
+ // maximum size should be unconstrained in both directions. |
+ EXPECT_EQ(buttons_size, client_view()->GetMinimumSize()); |
+ EXPECT_EQ(gfx::Size(), client_view()->GetMaximumSize()); |
+ |
+ // Ensure buttons are between these widths, for the constants below. |
+ EXPECT_LT(20, buttons_size.width()); |
+ EXPECT_GT(300, buttons_size.width()); |
+ |
+ // With no buttons, client view should match the contents view. |
+ SetDialogButtons(ui::DIALOG_BUTTON_NONE); |
+ SetSizeConstraints(gfx::Size(10, 15), gfx::Size(20, 25), gfx::Size(300, 350)); |
+ EXPECT_EQ(gfx::Size(10, 15), client_view()->GetMinimumSize()); |
+ EXPECT_EQ(gfx::Size(20, 25), client_view()->GetPreferredSize()); |
+ EXPECT_EQ(gfx::Size(300, 350), client_view()->GetMaximumSize()); |
+ |
+ // With buttons, size should increase vertically only. |
+ SetDialogButtons(ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL); |
+ EXPECT_EQ(gfx::Size(buttons_size.width(), 15 + buttons_size.height()), |
+ client_view()->GetMinimumSize()); |
+ EXPECT_EQ(gfx::Size(buttons_size.width(), 25 + buttons_size.height()), |
+ client_view()->GetPreferredSize()); |
+ EXPECT_EQ(gfx::Size(300, 350 + buttons_size.height()), |
+ client_view()->GetMaximumSize()); |
+ |
+ // If the contents view gets bigger, it should take over the width. |
+ SetSizeConstraints(gfx::Size(400, 450), gfx::Size(500, 550), |
+ gfx::Size(600, 650)); |
+ EXPECT_EQ(gfx::Size(400, 450 + buttons_size.height()), |
+ client_view()->GetMinimumSize()); |
+ EXPECT_EQ(gfx::Size(500, 550 + buttons_size.height()), |
+ client_view()->GetPreferredSize()); |
+ EXPECT_EQ(gfx::Size(600, 650 + buttons_size.height()), |
+ client_view()->GetMaximumSize()); |
+} |
+ |
+// Ensure button widths are linked under MD. |
+TEST_F(DialogClientViewTest, LinkedWidths) { |
+ ui::test::MaterialDesignControllerTestAPI md_test_api( |
+ ui::MaterialDesignController::MATERIAL_NORMAL); |
+ md_test_api.SetSecondaryUiMaterial(true); |
+ SetLongCancelLabel(); |
+ |
+ SetDialogButtons(ui::DIALOG_BUTTON_OK); |
+ CheckContentsIsSetToPreferredSize(); |
+ const int ok_button_only_width = client_view()->ok_button()->width(); |
+ |
+ SetDialogButtons(ui::DIALOG_BUTTON_CANCEL); |
+ CheckContentsIsSetToPreferredSize(); |
+ const int cancel_button_width = client_view()->cancel_button()->width(); |
+ |
+ // Ensure the single buttons have different preferred widths when alone, and |
+ // that the Cancel button is bigger (so that it dominates the size). |
+ EXPECT_GT(cancel_button_width, ok_button_only_width); |
+ |
+ SetDialogButtons(ui::DIALOG_BUTTON_CANCEL | ui::DIALOG_BUTTON_OK); |
+ CheckContentsIsSetToPreferredSize(); |
+ |
+ // OK button should now match the bigger, cancel button. |
+ EXPECT_EQ(cancel_button_width, client_view()->ok_button()->width()); |
+ |
+ // But not under non-MD. |
+ md_test_api.SetSecondaryUiMaterial(false); |
+ client_view()->UpdateDialogButtons(); |
+ CheckContentsIsSetToPreferredSize(); |
+ EXPECT_EQ(ok_button_only_width, client_view()->ok_button()->width()); |
+ md_test_api.SetSecondaryUiMaterial(true); |
+ |
+ // The extra view should also match, if it's a button. |
+ LabelButton* extra_button = new LabelButton(nullptr, base::string16()); |
+ SetExtraView(extra_button); |
+ CheckContentsIsSetToPreferredSize(); |
+ EXPECT_EQ(cancel_button_width, extra_button->width()); |
+ |
+ // Remove |extra_button| from the View hierarchy so that it can be replaced. |
+ delete extra_button; |
+ |
+ // Non-buttons should always be sized to their preferred size. |
+ View* boring_view = new StaticSizedView(gfx::Size(20, 20)); |
+ SetExtraView(boring_view); |
+ CheckContentsIsSetToPreferredSize(); |
+ EXPECT_EQ(20, boring_view->width()); |
} |
} // namespace views |