Commit ceac8c02 authored by Wei Li's avatar Wei Li Committed by Commit Bot

Refactor MessageBoxView

Instead of using an InitParams with options, this CL refactors to use
various setter functions to set the optional views and layout
parameters.

The above change will allow the default constructability of
MessageBoxView class.

BUG=1108460

Change-Id: I16a31e95fabef2b46281889777146e2888cde9cf
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2367645
Commit-Queue: Wei Li <weili@chromium.org>
Reviewed-by: default avatarScott Violet <sky@chromium.org>
Cr-Commit-Position: refs/heads/master@{#801053}
parent 81b86278
...@@ -23,8 +23,8 @@ class CancelCastingDialog : public views::DialogDelegateView { ...@@ -23,8 +23,8 @@ class CancelCastingDialog : public views::DialogDelegateView {
public: public:
CancelCastingDialog(base::OnceCallback<void(bool)> callback) CancelCastingDialog(base::OnceCallback<void(bool)> callback)
: callback_(std::move(callback)) { : callback_(std::move(callback)) {
AddChildView(new views::MessageBoxView(views::MessageBoxView::InitParams( AddChildView(new views::MessageBoxView(
l10n_util::GetStringUTF16(IDS_DESKTOP_CASTING_ACTIVE_MESSAGE)))); l10n_util::GetStringUTF16(IDS_DESKTOP_CASTING_ACTIVE_MESSAGE)));
SetLayoutManager(std::make_unique<views::FillLayout>()); SetLayoutManager(std::make_unique<views::FillLayout>());
SetTitle(l10n_util::GetStringUTF16(IDS_DESKTOP_CASTING_ACTIVE_TITLE)); SetTitle(l10n_util::GetStringUTF16(IDS_DESKTOP_CASTING_ACTIVE_TITLE));
SetShowCloseButton(false); SetShowCloseButton(false);
......
...@@ -66,9 +66,8 @@ ExternalProtocolDialog::ExternalProtocolDialog(WebContents* web_contents, ...@@ -66,9 +66,8 @@ ExternalProtocolDialog::ExternalProtocolDialog(WebContents* web_contents,
ui::DIALOG_BUTTON_OK, ui::DIALOG_BUTTON_OK,
l10n_util::GetStringUTF16(IDS_EXTERNAL_PROTOCOL_OK_BUTTON_TEXT)); l10n_util::GetStringUTF16(IDS_EXTERNAL_PROTOCOL_OK_BUTTON_TEXT));
views::MessageBoxView::InitParams params((base::string16())); message_box_view_ = new views::MessageBoxView();
params.message_width = kMessageWidth; message_box_view_->SetMessageWidth(kMessageWidth);
message_box_view_ = new views::MessageBoxView(params);
gfx::NativeWindow parent_window; gfx::NativeWindow parent_window;
if (web_contents) { if (web_contents) {
......
...@@ -58,10 +58,8 @@ CrostiniPackageInstallFailureView::CrostiniPackageInstallFailureView( ...@@ -58,10 +58,8 @@ CrostiniPackageInstallFailureView::CrostiniPackageInstallFailureView(
nullptr); nullptr);
AddChildView(message_label); AddChildView(message_label);
views::MessageBoxView::InitParams error_box_init_params(
base::UTF8ToUTF16(error_message));
views::MessageBoxView* error_box = views::MessageBoxView* error_box =
new views::MessageBoxView(error_box_init_params); new views::MessageBoxView(base::UTF8ToUTF16(error_message));
AddChildView(error_box); AddChildView(error_box);
set_close_on_deactivate(true); set_close_on_deactivate(true);
......
...@@ -90,9 +90,8 @@ ExternalProtocolDialog::ExternalProtocolDialog( ...@@ -90,9 +90,8 @@ ExternalProtocolDialog::ExternalProtocolDialog(
&ExternalProtocolHandler::RecordHandleStateMetrics, &ExternalProtocolHandler::RecordHandleStateMetrics,
false /* checkbox_selected */, ExternalProtocolHandler::BLOCK)); false /* checkbox_selected */, ExternalProtocolHandler::BLOCK));
views::MessageBoxView::InitParams params( message_box_view_ =
GetMessageTextForOrigin(initiating_origin_)); new views::MessageBoxView(GetMessageTextForOrigin(initiating_origin_));
message_box_view_ = new views::MessageBoxView(params);
ChromeLayoutProvider* provider = ChromeLayoutProvider::Get(); ChromeLayoutProvider* provider = ChromeLayoutProvider::Get();
set_margins( set_margins(
......
...@@ -93,15 +93,10 @@ JavaScriptTabModalDialogViewViews::JavaScriptTabModalDialogViewViews( ...@@ -93,15 +93,10 @@ JavaScriptTabModalDialogViewViews::JavaScriptTabModalDialogViewViews(
}, },
base::Unretained(this))); base::Unretained(this)));
int options = views::MessageBoxView::DETECT_DIRECTIONALITY; message_box_view_ = new views::MessageBoxView(
message_text, /* detect_directionality = */ true);
if (dialog_type == content::JAVASCRIPT_DIALOG_TYPE_PROMPT) if (dialog_type == content::JAVASCRIPT_DIALOG_TYPE_PROMPT)
options |= views::MessageBoxView::HAS_PROMPT_FIELD; message_box_view_->SetPromptField(default_prompt_text);
views::MessageBoxView::InitParams params(message_text);
params.options = options;
params.default_prompt = default_prompt_text;
message_box_view_ = new views::MessageBoxView(params);
DCHECK(message_box_view_);
SetLayoutManager(std::make_unique<views::FillLayout>()); SetLayoutManager(std::make_unique<views::FillLayout>());
AddChildView(message_box_view_); AddChildView(message_box_view_);
......
...@@ -214,8 +214,7 @@ MessageBoxDialog::MessageBoxDialog(const base::string16& title, ...@@ -214,8 +214,7 @@ MessageBoxDialog::MessageBoxDialog(const base::string16& title,
bool is_system_modal) bool is_system_modal)
: window_title_(title), : window_title_(title),
type_(type), type_(type),
message_box_view_(new views::MessageBoxView( message_box_view_(new views::MessageBoxView(message)),
views::MessageBoxView::InitParams(message))),
is_system_modal_(is_system_modal) { is_system_modal_(is_system_modal) {
SetButtons(type_ == chrome::MESSAGE_BOX_TYPE_QUESTION SetButtons(type_ == chrome::MESSAGE_BOX_TYPE_QUESTION
? ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL ? ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL
......
...@@ -47,11 +47,10 @@ TabModalConfirmDialogViews::TabModalConfirmDialogViews( ...@@ -47,11 +47,10 @@ TabModalConfirmDialogViews::TabModalConfirmDialogViews(
if (bool(default_button)) if (bool(default_button))
SetDefaultButton(*default_button); SetDefaultButton(*default_button);
views::MessageBoxView::InitParams init_params(delegate_->GetDialogMessage()); message_box_view_ = new views::MessageBoxView(delegate_->GetDialogMessage());
init_params.inter_row_vertical_spacing = message_box_view_->SetInterRowVerticalSpacing(
ChromeLayoutProvider::Get()->GetDistanceMetric( ChromeLayoutProvider::Get()->GetDistanceMetric(
views::DISTANCE_UNRELATED_CONTROL_VERTICAL); views::DISTANCE_UNRELATED_CONTROL_VERTICAL));
message_box_view_ = new views::MessageBoxView(init_params);
base::string16 link_text(delegate_->GetLinkText()); base::string16 link_text(delegate_->GetLinkText());
if (!link_text.empty()) { if (!link_text.empty()) {
......
...@@ -48,11 +48,11 @@ UpdateRecommendedMessageBox::UpdateRecommendedMessageBox() { ...@@ -48,11 +48,11 @@ UpdateRecommendedMessageBox::UpdateRecommendedMessageBox() {
IDS_UPDATE_RECOMMENDED, BrowserList::GetIncognitoBrowserCount()); IDS_UPDATE_RECOMMENDED, BrowserList::GetIncognitoBrowserCount());
#endif #endif
views::MessageBoxView::InitParams params(update_message);
params.message_width = ChromeLayoutProvider::Get()->GetDistanceMetric(
ChromeDistanceMetric::DISTANCE_MODAL_DIALOG_PREFERRED_WIDTH);
// Also deleted when the window closes. // Also deleted when the window closes.
message_box_view_ = new views::MessageBoxView(params); message_box_view_ = new views::MessageBoxView(update_message);
message_box_view_->SetMessageWidth(
ChromeLayoutProvider::Get()->GetDistanceMetric(
ChromeDistanceMetric::DISTANCE_MODAL_DIALOG_PREFERRED_WIDTH));
chrome::RecordDialogCreation(chrome::DialogIdentifier::UPDATE_RECOMMENDED); chrome::RecordDialogCreation(chrome::DialogIdentifier::UPDATE_RECOMMENDED);
} }
......
...@@ -21,16 +21,12 @@ namespace javascript_dialogs { ...@@ -21,16 +21,12 @@ namespace javascript_dialogs {
AppModalDialogViewViews::AppModalDialogViewViews( AppModalDialogViewViews::AppModalDialogViewViews(
AppModalDialogController* controller) AppModalDialogController* controller)
: controller_(controller) { : controller_(controller) {
int options = views::MessageBoxView::DETECT_DIRECTIONALITY; message_box_view_ = new views::MessageBoxView(
controller->message_text(), /* detect_directionality = */ true);
if (controller->javascript_dialog_type() == if (controller->javascript_dialog_type() ==
content::JAVASCRIPT_DIALOG_TYPE_PROMPT) content::JAVASCRIPT_DIALOG_TYPE_PROMPT) {
options |= views::MessageBoxView::HAS_PROMPT_FIELD; message_box_view_->SetPromptField(controller->default_prompt_text());
}
views::MessageBoxView::InitParams params(controller->message_text());
params.options = options;
params.default_prompt = controller->default_prompt_text();
message_box_view_ = new views::MessageBoxView(params);
DCHECK(message_box_view_);
message_box_view_->AddAccelerator( message_box_view_->AddAccelerator(
ui::Accelerator(ui::VKEY_C, ui::EF_CONTROL_DOWN)); ui::Accelerator(ui::VKEY_C, ui::EF_CONTROL_DOWN));
......
...@@ -67,8 +67,7 @@ MessageBox::Core::Core(const base::string16& title_label, ...@@ -67,8 +67,7 @@ MessageBox::Core::Core(const base::string16& title_label,
: title_label_(title_label), : title_label_(title_label),
result_callback_(std::move(result_callback)), result_callback_(std::move(result_callback)),
message_box_(message_box), message_box_(message_box),
message_box_view_(new views::MessageBoxView( message_box_view_(new views::MessageBoxView(message_label)) {
views::MessageBoxView::InitParams(message_label))) {
DCHECK(message_box_); DCHECK(message_box_);
DialogDelegate::SetButtonLabel(ui::DIALOG_BUTTON_OK, ok_label); DialogDelegate::SetButtonLabel(ui::DIALOG_BUTTON_OK, ok_label);
DialogDelegate::SetButtonLabel(ui::DIALOG_BUTTON_CANCEL, cancel_label); DialogDelegate::SetButtonLabel(ui::DIALOG_BUTTON_CANCEL, cancel_label);
......
...@@ -1074,6 +1074,7 @@ test("views_unittests") { ...@@ -1074,6 +1074,7 @@ test("views_unittests") {
"controls/menu/submenu_view_unittest.cc", "controls/menu/submenu_view_unittest.cc",
"controls/menu/test_menu_item_view.cc", "controls/menu/test_menu_item_view.cc",
"controls/menu/test_menu_item_view.h", "controls/menu/test_menu_item_view.h",
"controls/message_box_view_unittest.cc",
"controls/native/native_view_host_test_base.cc", "controls/native/native_view_host_test_base.cc",
"controls/native/native_view_host_test_base.h", "controls/native/native_view_host_test_base.h",
"controls/native/native_view_host_unittest.cc", "controls/native/native_view_host_unittest.cc",
......
...@@ -74,19 +74,62 @@ namespace views { ...@@ -74,19 +74,62 @@ namespace views {
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// MessageBoxView, public: // MessageBoxView, public:
MessageBoxView::InitParams::InitParams(const base::string16& message) MessageBoxView::MessageBoxView(const base::string16& message,
: options(NO_OPTIONS), bool detect_directionality)
message(message), : inter_row_vertical_spacing_(LayoutProvider::Get()->GetDistanceMetric(
message_width(kDefaultMessageWidth), DISTANCE_RELATED_CONTROL_VERTICAL)),
inter_row_vertical_spacing(LayoutProvider::Get()->GetDistanceMetric( message_width_(kDefaultMessageWidth) {
DISTANCE_RELATED_CONTROL_VERTICAL)) {} const LayoutProvider* provider = LayoutProvider::Get();
MessageBoxView::InitParams::~InitParams() = default; auto message_contents = std::make_unique<View>();
// We explicitly set insets on the message contents instead of the scroll view
MessageBoxView::MessageBoxView(const InitParams& params) // so that the scroll view borders are not capped by dialog insets.
: inter_row_vertical_spacing_(params.inter_row_vertical_spacing), message_contents->SetBorder(CreateEmptyBorder(GetHorizontalInsets(provider)));
message_width_(params.message_width) { message_contents->SetLayoutManager(std::make_unique<views::BoxLayout>(
Init(std::move(params)); views::BoxLayout::Orientation::kVertical));
auto add_label = [&message_contents, this](
const base::string16& text, bool multi_line,
gfx::HorizontalAlignment alignment) {
auto message_label =
std::make_unique<Label>(text, style::CONTEXT_MESSAGE_BOX_BODY_TEXT);
message_label->SetMultiLine(!text.empty());
message_label->SetAllowCharacterBreak(true);
message_label->SetHorizontalAlignment(alignment);
message_labels_.push_back(
message_contents->AddChildView(std::move(message_label)));
};
if (detect_directionality) {
std::vector<base::string16> texts;
SplitStringIntoParagraphs(message, &texts);
for (const auto& text : texts) {
// Avoid empty multi-line labels, which have a height of 0.
add_label(text, !text.empty(), gfx::ALIGN_TO_HEAD);
}
} else {
add_label(message, true, gfx::ALIGN_LEFT);
}
auto scroll_view = std::make_unique<ScrollView>();
scroll_view->ClipHeightTo(0, provider->GetDistanceMetric(
DISTANCE_DIALOG_SCROLLABLE_AREA_MAX_HEIGHT));
scroll_view->SetContents(std::move(message_contents));
scroll_view_ = AddChildView(std::move(scroll_view));
// Don't enable text selection if multiple labels are used, since text
// selection can't span multiple labels.
if (message_labels_.size() == 1u)
message_labels_[0]->SetSelectable(true);
prompt_field_ = AddChildView(std::make_unique<Textfield>());
prompt_field_->SetAccessibleName(message);
prompt_field_->SetVisible(false);
checkbox_ = AddChildView(std::make_unique<Checkbox>());
checkbox_->SetVisible(false);
link_ = AddChildView(std::make_unique<Link>());
link_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
link_->SetVisible(false);
ResetLayoutManager();
} }
MessageBoxView::~MessageBoxView() = default; MessageBoxView::~MessageBoxView() = default;
...@@ -100,20 +143,18 @@ bool MessageBoxView::IsCheckBoxSelected() { ...@@ -100,20 +143,18 @@ bool MessageBoxView::IsCheckBoxSelected() {
} }
void MessageBoxView::SetCheckBoxLabel(const base::string16& label) { void MessageBoxView::SetCheckBoxLabel(const base::string16& label) {
if (checkbox_) { DCHECK(checkbox_);
checkbox_->SetText(label); if (checkbox_->GetVisible() && checkbox_->GetText() == label)
} else { return;
// First remove the existing layout manager since it will DCHECK
// if a view is added through AddChildView rather than checkbox_->SetText(label);
// GridLayout::AddView. checkbox_->SetVisible(true);
SetLayoutManager(nullptr); ResetLayoutManager();
checkbox_ = AddChildView(std::make_unique<Checkbox>(label));
ResetLayoutManager();
}
} }
void MessageBoxView::SetCheckBoxSelected(bool selected) { void MessageBoxView::SetCheckBoxSelected(bool selected) {
if (!checkbox_) // Only update the checkbox's state after the checkbox is shown.
if (!checkbox_->GetVisible())
return; return;
checkbox_->SetChecked(selected); checkbox_->SetChecked(selected);
} }
...@@ -122,12 +163,13 @@ void MessageBoxView::SetLink(const base::string16& text, ...@@ -122,12 +163,13 @@ void MessageBoxView::SetLink(const base::string16& text,
Link::ClickedCallback callback) { Link::ClickedCallback callback) {
DCHECK(!text.empty()); DCHECK(!text.empty());
DCHECK(!callback.is_null()); DCHECK(!callback.is_null());
DCHECK(!link_); DCHECK(link_);
// See the comment in SetCheckBoxLabel();
SetLayoutManager(nullptr);
link_ = AddChildView(std::make_unique<Link>(text));
link_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
link_->set_callback(std::move(callback)); link_->set_callback(std::move(callback));
if (link_->GetVisible() && link_->GetText() == text)
return;
link_->SetText(text);
link_->SetVisible(true);
ResetLayoutManager(); ResetLayoutManager();
} }
...@@ -135,6 +177,31 @@ void MessageBoxView::GetAccessibleNodeData(ui::AXNodeData* node_data) { ...@@ -135,6 +177,31 @@ void MessageBoxView::GetAccessibleNodeData(ui::AXNodeData* node_data) {
node_data->role = ax::mojom::Role::kAlertDialog; node_data->role = ax::mojom::Role::kAlertDialog;
} }
void MessageBoxView::SetInterRowVerticalSpacing(int spacing) {
if (inter_row_vertical_spacing_ == spacing)
return;
inter_row_vertical_spacing_ = spacing;
ResetLayoutManager();
}
void MessageBoxView::SetMessageWidth(int width) {
if (message_width_ == width)
return;
message_width_ = width;
ResetLayoutManager();
}
void MessageBoxView::SetPromptField(const base::string16& default_prompt) {
DCHECK(prompt_field_);
if (prompt_field_->GetVisible() && prompt_field_->GetText() == default_prompt)
return;
prompt_field_->SetText(default_prompt);
prompt_field_->SetVisible(true);
ResetLayoutManager();
}
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// MessageBoxView, View overrides: // MessageBoxView, View overrides:
...@@ -173,56 +240,6 @@ bool MessageBoxView::AcceleratorPressed(const ui::Accelerator& accelerator) { ...@@ -173,56 +240,6 @@ bool MessageBoxView::AcceleratorPressed(const ui::Accelerator& accelerator) {
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// MessageBoxView, private: // MessageBoxView, private:
void MessageBoxView::Init(const InitParams& params) {
const LayoutProvider* provider = LayoutProvider::Get();
auto message_contents = std::make_unique<View>();
// We explicitly set insets on the message contents instead of the scroll view
// so that the scroll view borders are not capped by dialog insets.
message_contents->SetBorder(CreateEmptyBorder(GetHorizontalInsets(provider)));
message_contents->SetLayoutManager(std::make_unique<views::BoxLayout>(
views::BoxLayout::Orientation::kVertical));
auto add_label = [&message_contents, this](
const base::string16& text, bool multi_line,
gfx::HorizontalAlignment alignment) {
auto message_label =
std::make_unique<Label>(text, style::CONTEXT_MESSAGE_BOX_BODY_TEXT);
message_label->SetMultiLine(!text.empty());
message_label->SetAllowCharacterBreak(true);
message_label->SetHorizontalAlignment(alignment);
message_labels_.push_back(
message_contents->AddChildView(std::move(message_label)));
};
if (params.options & DETECT_DIRECTIONALITY) {
std::vector<base::string16> texts;
SplitStringIntoParagraphs(params.message, &texts);
for (const auto& text : texts) {
// Avoid empty multi-line labels, which have a height of 0.
add_label(text, !text.empty(), gfx::ALIGN_TO_HEAD);
}
} else {
add_label(params.message, true, gfx::ALIGN_LEFT);
}
auto scroll_view = std::make_unique<ScrollView>();
scroll_view->ClipHeightTo(0, provider->GetDistanceMetric(
DISTANCE_DIALOG_SCROLLABLE_AREA_MAX_HEIGHT));
scroll_view->SetContents(std::move(message_contents));
scroll_view_ = AddChildView(std::move(scroll_view));
// Don't enable text selection if multiple labels are used, since text
// selection can't span multiple labels.
if (message_labels_.size() == 1u)
message_labels_[0]->SetSelectable(true);
if (params.options & HAS_PROMPT_FIELD) {
auto prompt_field = std::make_unique<Textfield>();
prompt_field->SetText(params.default_prompt);
prompt_field->SetAccessibleName(params.message);
prompt_field_ = AddChildView(std::move(prompt_field));
}
ResetLayoutManager();
}
void MessageBoxView::ResetLayoutManager() { void MessageBoxView::ResetLayoutManager() {
// Initialize the Grid Layout Manager used for this dialog box. // Initialize the Grid Layout Manager used for this dialog box.
GridLayout* layout = SetLayoutManager(std::make_unique<views::GridLayout>()); GridLayout* layout = SetLayoutManager(std::make_unique<views::GridLayout>());
...@@ -237,7 +254,8 @@ void MessageBoxView::ResetLayoutManager() { ...@@ -237,7 +254,8 @@ void MessageBoxView::ResetLayoutManager() {
// Column set for extra elements, if any. // Column set for extra elements, if any.
constexpr int kExtraViewColumnSetId = 1; constexpr int kExtraViewColumnSetId = 1;
if (prompt_field_ || checkbox_ || link_) { if (prompt_field_->GetVisible() || checkbox_->GetVisible() ||
link_->GetVisible()) {
auto horizontal_insets = GetHorizontalInsets(provider); auto horizontal_insets = GetHorizontalInsets(provider);
column_set = layout->AddColumnSet(kExtraViewColumnSetId); column_set = layout->AddColumnSet(kExtraViewColumnSetId);
column_set->AddPaddingColumn(0, horizontal_insets.left()); column_set->AddPaddingColumn(0, horizontal_insets.left());
...@@ -250,21 +268,21 @@ void MessageBoxView::ResetLayoutManager() { ...@@ -250,21 +268,21 @@ void MessageBoxView::ResetLayoutManager() {
layout->AddExistingView(scroll_view_); layout->AddExistingView(scroll_view_);
views::DialogContentType trailing_content_type = views::TEXT; views::DialogContentType trailing_content_type = views::TEXT;
if (prompt_field_) { if (prompt_field_->GetVisible()) {
layout->AddPaddingRow(0, inter_row_vertical_spacing_); layout->AddPaddingRow(0, inter_row_vertical_spacing_);
layout->StartRow(0, kExtraViewColumnSetId); layout->StartRow(0, kExtraViewColumnSetId);
layout->AddExistingView(prompt_field_); layout->AddExistingView(prompt_field_);
trailing_content_type = views::CONTROL; trailing_content_type = views::CONTROL;
} }
if (checkbox_) { if (checkbox_->GetVisible()) {
layout->AddPaddingRow(0, inter_row_vertical_spacing_); layout->AddPaddingRow(0, inter_row_vertical_spacing_);
layout->StartRow(0, kExtraViewColumnSetId); layout->StartRow(0, kExtraViewColumnSetId);
layout->AddExistingView(checkbox_); layout->AddExistingView(checkbox_);
trailing_content_type = views::TEXT; trailing_content_type = views::TEXT;
} }
if (link_) { if (link_->GetVisible()) {
layout->AddPaddingRow(0, inter_row_vertical_spacing_); layout->AddPaddingRow(0, inter_row_vertical_spacing_);
layout->StartRow(0, kExtraViewColumnSetId); layout->StartRow(0, kExtraViewColumnSetId);
layout->AddExistingView(link_); layout->AddExistingView(link_);
...@@ -277,6 +295,8 @@ void MessageBoxView::ResetLayoutManager() { ...@@ -277,6 +295,8 @@ void MessageBoxView::ResetLayoutManager() {
// controls as padding columns. Only apply the missing vertical insets. // controls as padding columns. Only apply the missing vertical insets.
border_insets.Set(border_insets.top(), 0, border_insets.bottom(), 0); border_insets.Set(border_insets.top(), 0, border_insets.bottom(), 0);
SetBorder(CreateEmptyBorder(border_insets)); SetBorder(CreateEmptyBorder(border_insets));
InvalidateLayout();
} }
gfx::Insets MessageBoxView::GetHorizontalInsets( gfx::Insets MessageBoxView::GetHorizontalInsets(
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <vector> #include <vector>
#include "base/gtest_prod_util.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/strings/string16.h" #include "base/strings/string16.h"
#include "ui/gfx/geometry/insets.h" #include "ui/gfx/geometry/insets.h"
...@@ -30,31 +31,17 @@ class VIEWS_EXPORT MessageBoxView : public View { ...@@ -30,31 +31,17 @@ class VIEWS_EXPORT MessageBoxView : public View {
public: public:
METADATA_HEADER(MessageBoxView); METADATA_HEADER(MessageBoxView);
enum Options { // |detect_directionality| indicates whether |message|'s directionality is
NO_OPTIONS = 0, // auto-detected.
// For a message from a web page (not from Chrome's UI), such as script // For a message from a web page (not from Chrome's UI), such as script
// dialog text, each paragraph's directionality is auto-detected using the // dialog text, each paragraph's directionality is auto-detected using the
// directionality of the paragraph's first strong character's. Please refer // directionality of the paragraph's first strong character's. Please refer
// to HTML5 spec for details. // to HTML5 spec for details.
// http://dev.w3.org/html5/spec/Overview.html#text-rendered-in-native-user-interfaces: // http://dev.w3.org/html5/spec/Overview.html#text-rendered-in-native-user-interfaces:
// The spec does not say anything about alignment. And we choose to // The spec does not say anything about alignment. And we choose to
// align all paragraphs according to the direction of the first paragraph. // align all paragraphs according to the direction of the first paragraph.
DETECT_DIRECTIONALITY = 1 << 0, explicit MessageBoxView(const base::string16& message = base::string16(),
HAS_PROMPT_FIELD = 1 << 1, bool detect_directionality = false);
};
struct VIEWS_EXPORT InitParams {
explicit InitParams(const base::string16& message);
~InitParams();
uint16_t options;
base::string16 message;
base::string16 default_prompt;
int message_width;
int inter_row_vertical_spacing;
};
explicit MessageBoxView(const InitParams& params);
~MessageBoxView() override; ~MessageBoxView() override;
...@@ -85,6 +72,12 @@ class VIEWS_EXPORT MessageBoxView : public View { ...@@ -85,6 +72,12 @@ class VIEWS_EXPORT MessageBoxView : public View {
// View: // View:
void GetAccessibleNodeData(ui::AXNodeData* node_data) override; void GetAccessibleNodeData(ui::AXNodeData* node_data) override;
void SetInterRowVerticalSpacing(int spacing);
void SetMessageWidth(int width);
// Adds a prompt field with |default_prompt| as the displayed text.
void SetPromptField(const base::string16& default_prompt);
protected: protected:
// View: // View:
void ViewHierarchyChanged( void ViewHierarchyChanged(
...@@ -93,12 +86,12 @@ class VIEWS_EXPORT MessageBoxView : public View { ...@@ -93,12 +86,12 @@ class VIEWS_EXPORT MessageBoxView : public View {
bool AcceleratorPressed(const ui::Accelerator& accelerator) override; bool AcceleratorPressed(const ui::Accelerator& accelerator) override;
private: private:
// Sets up the layout manager and initializes the message labels and prompt FRIEND_TEST_ALL_PREFIXES(MessageBoxViewTest, CheckMessageOnlySize);
// field. This should only be called once, from the constructor. FRIEND_TEST_ALL_PREFIXES(MessageBoxViewTest, CheckWithOptionalViewsSize);
void Init(const InitParams& params); FRIEND_TEST_ALL_PREFIXES(MessageBoxViewTest, CheckInterRowHeightChange);
// Sets up the layout manager based on currently initialized views. Should be // Sets up the layout manager based on currently initialized views and layout
// called when a view is initialized or changed. // parameters. Should be called when a view is initialized or changed.
void ResetLayoutManager(); void ResetLayoutManager();
// Return the proper horizontal insets based on the given layout provider. // Return the proper horizontal insets based on the given layout provider.
...@@ -120,7 +113,7 @@ class VIEWS_EXPORT MessageBoxView : public View { ...@@ -120,7 +113,7 @@ class VIEWS_EXPORT MessageBoxView : public View {
Link* link_ = nullptr; Link* link_ = nullptr;
// Spacing between rows in the grid layout. // Spacing between rows in the grid layout.
const int inter_row_vertical_spacing_ = 0; int inter_row_vertical_spacing_ = 0;
// Maximum width of the message label. // Maximum width of the message label.
int message_width_ = 0; int message_width_ = 0;
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/views/controls/message_box_view.h"
#include <algorithm>
#include <memory>
#include "base/bind_helpers.h"
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/geometry/insets.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/views/controls/button/checkbox.h"
#include "ui/views/controls/link.h"
#include "ui/views/controls/scroll_view.h"
#include "ui/views/controls/textfield/textfield.h"
#include "ui/views/layout/layout_provider.h"
#include "ui/views/test/views_test_base.h"
namespace views {
namespace {
// The default mesage width same as defined in message_box_view.cc.
constexpr int kDefaultMessageWidth = 400;
const base::string16 kDefaultMessage =
base::ASCIIToUTF16("This is a test message for MessageBoxView.");
} // namespace
class MessageBoxViewTest : public ViewsTestBase {
public:
MessageBoxViewTest() = default;
MessageBoxViewTest(const MessageBoxViewTest&) = delete;
MessageBoxViewTest& operator=(const MessageBoxViewTest&) = delete;
~MessageBoxViewTest() override = default;
protected:
void SetUp() override {
ViewsTestBase::SetUp();
message_box_ = std::make_unique<MessageBoxView>(kDefaultMessage);
provider_ = LayoutProvider::Get();
}
std::unique_ptr<MessageBoxView> message_box_;
const LayoutProvider* provider_;
};
TEST_F(MessageBoxViewTest, CheckMessageOnlySize) {
message_box_->SizeToPreferredSize();
gfx::Insets box_border =
provider_->GetDialogInsetsForContentType(views::TEXT, views::TEXT);
gfx::Size scroll_size = message_box_->scroll_view_->size();
scroll_size.Enlarge(0, box_border.top() + box_border.bottom());
EXPECT_EQ(scroll_size, message_box_->size());
}
TEST_F(MessageBoxViewTest, CheckWithOptionalViewsSize) {
message_box_->SetPromptField(base::string16());
message_box_->SizeToPreferredSize();
gfx::Insets box_border =
provider_->GetDialogInsetsForContentType(views::TEXT, views::CONTROL);
gfx::Size scroll_size = message_box_->scroll_view_->size();
gfx::Size prompt_size = message_box_->prompt_field_->size();
gfx::Size content_size(std::max(scroll_size.width(), prompt_size.width()),
scroll_size.height() + prompt_size.height());
content_size.Enlarge(0, box_border.top() + box_border.bottom() +
message_box_->inter_row_vertical_spacing_);
EXPECT_EQ(content_size, message_box_->size());
// Add a checkbox and a link.
message_box_->SetCheckBoxLabel(base::ASCIIToUTF16("A checkbox"));
message_box_->SetLink(base::ASCIIToUTF16("Link to display"),
base::DoNothing());
message_box_->SizeToPreferredSize();
box_border =
provider_->GetDialogInsetsForContentType(views::TEXT, views::TEXT);
gfx::Size checkbox_size = message_box_->checkbox_->size();
gfx::Size link_size = message_box_->link_->size();
content_size =
gfx::Size(std::max(std::max(scroll_size.width(), prompt_size.width()),
std::max(checkbox_size.width(), link_size.width())),
scroll_size.height() + prompt_size.height() +
checkbox_size.height() + link_size.height());
content_size.Enlarge(0, box_border.top() + box_border.bottom() +
3 * message_box_->inter_row_vertical_spacing_);
EXPECT_EQ(content_size, message_box_->size());
}
TEST_F(MessageBoxViewTest, CheckMessageWidthChange) {
message_box_->SizeToPreferredSize();
EXPECT_EQ(kDefaultMessageWidth, message_box_->width());
static constexpr int kNewWidth = 210;
message_box_->SetMessageWidth(kNewWidth);
message_box_->SizeToPreferredSize();
EXPECT_EQ(kNewWidth, message_box_->width());
}
TEST_F(MessageBoxViewTest, CheckInterRowHeightChange) {
message_box_->SetPromptField(base::string16());
message_box_->SizeToPreferredSize();
int scroll_height = message_box_->scroll_view_->height();
int prompt_height = message_box_->prompt_field_->height();
gfx::Insets box_border =
provider_->GetDialogInsetsForContentType(views::TEXT, views::CONTROL);
int inter_row_spacing = message_box_->inter_row_vertical_spacing_;
EXPECT_EQ(
scroll_height + inter_row_spacing + prompt_height + box_border.height(),
message_box_->height());
static constexpr int kNewInterRowSpacing = 50;
EXPECT_NE(kNewInterRowSpacing, inter_row_spacing);
message_box_->SetInterRowVerticalSpacing(kNewInterRowSpacing);
message_box_->SizeToPreferredSize();
EXPECT_EQ(kNewInterRowSpacing, message_box_->inter_row_vertical_spacing_);
EXPECT_EQ(
scroll_height + kNewInterRowSpacing + prompt_height + box_border.height(),
message_box_->height());
}
} // namespace views
...@@ -33,7 +33,7 @@ void MessageBoxExample::CreateExampleView(View* container) { ...@@ -33,7 +33,7 @@ void MessageBoxExample::CreateExampleView(View* container) {
std::make_unique<BoxLayout>(BoxLayout::Orientation::kVertical)); std::make_unique<BoxLayout>(BoxLayout::Orientation::kVertical));
message_box_view_ = container->AddChildView(std::make_unique<MessageBoxView>( message_box_view_ = container->AddChildView(std::make_unique<MessageBoxView>(
MessageBoxView::InitParams(GetStringUTF16(IDS_MESSAGE_INTRO_LABEL)))); GetStringUTF16(IDS_MESSAGE_INTRO_LABEL)));
message_box_view_->SetCheckBoxLabel( message_box_view_->SetCheckBoxLabel(
GetStringUTF16(IDS_MESSAGE_CHECK_BOX_LABEL)); GetStringUTF16(IDS_MESSAGE_CHECK_BOX_LABEL));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment