Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(20)

Side by Side Diff: chrome/browser/ui/views/srt_prompt_dialog.cc

Issue 2795133002: Chrome Cleaner UI: Add a dialog class for the new UI (Closed)
Patch Set: No longer subclassing View for the details section Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2017 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 "chrome/browser/ui/views/srt_prompt_dialog.h"
6
7 #include <vector>
8
9 #include "base/strings/string16.h"
10 #include "chrome/app/vector_icons/vector_icons.h"
11 #include "chrome/browser/safe_browsing/srt_prompt_controller.h"
12 #include "chrome/browser/ui/browser.h"
13 #include "chrome/browser/ui/browser_dialogs.h"
14 #include "chrome/browser/ui/browser_window.h"
15 #include "chrome/browser/ui/chrome_web_modal_dialog_manager_delegate.h"
16 #include "components/constrained_window/constrained_window_views.h"
17 #include "components/web_modal/web_contents_modal_dialog_host.h"
18 #include "ui/base/ui_base_types.h"
19 #include "ui/events/event.h"
20 #include "ui/gfx/geometry/size.h"
21 #include "ui/gfx/native_widget_types.h"
22 #include "ui/gfx/paint_vector_icon.h"
23 #include "ui/gfx/text_constants.h"
24 #include "ui/native_theme/native_theme.h"
25 #include "ui/views/border.h"
26 #include "ui/views/controls/label.h"
27 #include "ui/views/controls/scroll_view.h"
28 #include "ui/views/controls/separator.h"
29 #include "ui/views/layout/box_layout.h"
30 #include "ui/views/layout/fill_layout.h"
31 #include "ui/views/layout/grid_layout.h"
32 #include "ui/views/layout/layout_constants.h"
33 #include "ui/views/widget/widget.h"
34
35 namespace chrome {
36
37 void ShowSRTPrompt(Browser* browser,
38 safe_browsing::SRTPromptController* controller) {
39 SRTPromptDialog* dialog = new SRTPromptDialog(controller);
40 dialog->Show(browser);
41 }
42
43 } // namespace chrome
44
45 namespace {
46
47 using LabelInfo = safe_browsing::SRTPromptController::LabelInfo;
48
49 constexpr int kDialogWidth = 448;
50 constexpr int kDetailsSectionMaxHeight = 150;
51 constexpr int kBulletColumnWidth = 10;
52 // Constants used for the layout of the label views.
53 constexpr int kMainColumSetId = 0;
54 constexpr int kBulletColumnSetId = 1;
55
56 // Returns a view containing |item| with insets defined by |top|, |left|,
57 // |bottom|, and |right|.
58 views::View* CreateViewWithInsets(views::View* item,
59 int top,
60 int left,
61 int bottom,
62 int right) {
63 views::View* view = new views::View();
64 view->SetLayoutManager(new views::FillLayout());
65 view->SetBorder(views::CreateEmptyBorder(top, left, bottom, right));
66 view->AddChildView(item);
67 return view;
68 }
69
70 // Helper function used by |CreateLabelView()| below that adds |labels| to
71 // |label_view|.
72 void AddLabelsToLabelView(views::View* label_view,
73 views::GridLayout* layout,
74 const std::vector<LabelInfo>& labels) {
75 static constexpr base::char16 kBulletPoint[] = {0x2022, 0};
76
77 bool first_label = true;
78 bool last_label_was_bullet = false;
79 for (const LabelInfo& label_info : labels) {
80 const bool is_bullet = label_info.type == LabelInfo::BULLET_ITEM;
81 views::Label* label = new views::Label(label_info.text);
82 label->SetMultiLine(true);
83 label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
84
85 // Do not add a padding row if
86 // - this is the first label being added, or
87 // - a bullet item is being added and the last label was also a bullet item.
88 bool skip_padding = first_label || (is_bullet && last_label_was_bullet);
89 if (!skip_padding)
90 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
91
92 layout->StartRow(0, is_bullet ? kBulletColumnSetId : kMainColumSetId);
93 if (is_bullet) {
94 views::Label* bullet = new views::Label(base::string16(kBulletPoint));
95 layout->AddView(bullet);
96 }
97 layout->AddView(label);
98
99 last_label_was_bullet = is_bullet;
100 first_label = false;
101 }
102 }
103
104 // Creates a view that displays two types of labels: multiline labels
105 // representing whole paragraphs or indented labels that are start with a bullet
106 // point.
107 //
108 // A vertical padding of size |top_vertical_space| is added before the labels.
109 views::View* CreateLabelView(int top_vertical_space,
110 const std::vector<LabelInfo>& labels) {
111 views::View* label_view = new views::View();
112 views::GridLayout* layout = new views::GridLayout(label_view);
113 layout->SetInsets(0, views::kButtonHEdgeMarginNew, 0,
114 views::kButtonHEdgeMarginNew);
115
116 label_view->SetLayoutManager(layout);
117
118 views::ColumnSet* main_column_set = layout->AddColumnSet(kMainColumSetId);
119 main_column_set->AddColumn(views::GridLayout::FILL,
120 views::GridLayout::LEADING,
121 /*resize_percent=*/1, views::GridLayout::USE_PREF,
122 /*fixed_width=*/0,
123 /*min_width=*/0);
124
125 views::ColumnSet* bullet_column_set_ =
126 layout->AddColumnSet(kBulletColumnSetId);
127 bullet_column_set_->AddPaddingColumn(
128 /*resize_percent=*/0, views::kUnrelatedControlLargeHorizontalSpacing);
129 bullet_column_set_->AddColumn(
130 views::GridLayout::FILL, views::GridLayout::LEADING,
131 /*resize_percent=*/0, views::GridLayout::USE_PREF,
132 /*fixed_width=*/0,
133 /*min_width=*/0);
134 bullet_column_set_->AddPaddingColumn(/*resize_percent=*/0,
135 kBulletColumnWidth);
136 bullet_column_set_->AddColumn(
137 views::GridLayout::FILL, views::GridLayout::LEADING,
138 /*resize_percent=*/1, views::GridLayout::USE_PREF,
139 /*fixed_width=*/0,
140 /*min_width=*/0);
141
142 if (top_vertical_space > 0)
143 layout->AddPaddingRow(/*vertical_resize=*/0, top_vertical_space);
144
145 AddLabelsToLabelView(label_view, layout, labels);
146
147 layout->AddPaddingRow(/*vertical_resize=*/0,
148 views::kUnrelatedControlLargeHorizontalSpacing);
149 return label_view;
150 }
151
152 } // namespace
153
154 ////////////////////////////////////////////////////////////////////////////////
155 // SRTPromptDialog
156
157 SRTPromptDialog::SRTPromptDialog(safe_browsing::SRTPromptController* controller)
158 : browser_(nullptr),
159 controller_(controller),
160 interaction_done_(false),
161 details_view_(nullptr),
162 details_button_(nullptr) {
163 DCHECK(controller_);
164
165 SetLayoutManager(new views::BoxLayout(
166 /*orientation=*/views::BoxLayout::kVertical,
167 /*inside_border_horizontal_spacing=*/0,
168 /*inside_border_vertical_spacing=*/views::kPanelVertMargin,
169 /*between_child_spacing=*/0));
170
171 AddChildView(CreateLabelView(0, controller_->GetMainText()));
172 AddChildView(new views::Separator());
173
174 // The details section starts off empty and will be populated when the user
175 // clicks the button to expand the details section. Its child views are
176 // removed when the section is closed.
177 details_view_ = new views::View();
sky 2017/04/06 16:01:02 move to member initializer?
alito 2017/04/06 17:35:37 Done.
178 details_view_->SetLayoutManager(new views::FillLayout());
179 details_view_->SetVisible(false);
180 AddChildView(details_view_);
181
182 details_button_ =
183 new views::LabelButton(this, controller_->GetShowDetailsLabel());
184 details_button_->SetEnabledTextColors(GetDetailsButtonColor());
185 UpdateDetailsButton();
186 AddChildView(CreateViewWithInsets(
187 details_button_, views::kPanelVertMargin, views::kButtonHEdgeMarginNew,
188 views::kPanelVertMargin, views::kButtonHEdgeMarginNew));
189 AddChildView(new views::Separator());
190 }
191
192 SRTPromptDialog::~SRTPromptDialog() {
193 // Make sure the controller is correctly notified in case the dialog widget is
194 // closed by some other means than the dialog buttons.
195 if (!interaction_done_)
196 controller_->Cancel();
197 }
198
199 void SRTPromptDialog::Show(Browser* browser) {
200 DCHECK(browser);
201 DCHECK(!browser_);
202
203 browser_ = browser;
204 constrained_window::CreateBrowserModalDialogViews(
205 this, browser_->window()->GetNativeWindow())
206 ->Show();
207 controller_->DialogShown();
208 }
209
210 // DialogModel overrides.
211
212 bool SRTPromptDialog::ShouldDefaultButtonBeBlue() const {
213 return true;
214 }
215
216 // WidgetDelegate overrides.
217
218 ui::ModalType SRTPromptDialog::GetModalType() const {
219 return ui::MODAL_TYPE_WINDOW;
220 }
221
222 base::string16 SRTPromptDialog::GetWindowTitle() const {
223 return controller_->GetWindowTitle();
224 }
225
226 // DialogDelegate overrides.
227
228 base::string16 SRTPromptDialog::GetDialogButtonLabel(
229 ui::DialogButton button) const {
230 DCHECK(button == ui::DIALOG_BUTTON_OK || button == ui::DIALOG_BUTTON_CANCEL);
231
232 if (button == ui::DIALOG_BUTTON_OK)
233 return controller_->GetAcceptButtonLabel();
234 return DialogDelegate::GetDialogButtonLabel(button);
235 }
236
237 bool SRTPromptDialog::Accept() {
238 if (!interaction_done_) {
239 interaction_done_ = true;
240 controller_->Accept();
241 }
242 return true;
243 }
244
245 bool SRTPromptDialog::Cancel() {
246 if (!interaction_done_) {
247 interaction_done_ = true;
248 controller_->Cancel();
249 }
250 return true;
251 }
252
253 // View overrides.
254
255 gfx::Size SRTPromptDialog::GetPreferredSize() const {
256 return gfx::Size(kDialogWidth, GetHeightForWidth(kDialogWidth));
257 }
258
259 // views::ButtonListener overrides.
260
261 void SRTPromptDialog::ButtonPressed(views::Button* sender,
262 const ui::Event& event) {
263 DCHECK_EQ(sender, details_button_);
264 DCHECK(browser_);
265
266 details_view_->SetVisible(!details_view_->visible());
267 if (details_view_->visible()) {
268 // Populate the details view adding the main message view inside a scroll
269 // view.
270 views::View* label_view =
271 CreateLabelView(views::kUnrelatedControlLargeHorizontalSpacing,
272 controller_->GetDetailsText());
273 views::ScrollView* scroll_view = new views::ScrollView();
274 scroll_view->ClipHeightTo(/*min_height=*/0, kDetailsSectionMaxHeight);
275 scroll_view->SetContents(label_view);
276 details_view_->AddChildView(scroll_view);
277 } else {
278 details_view_->RemoveAllChildViews(/*delete_children=*/true);
279 }
280
281 UpdateDetailsButton();
282
283 ChromeWebModalDialogManagerDelegate* manager = browser_;
284 constrained_window::UpdateWidgetModalDialogPosition(
285 GetWidget(), manager->GetWebContentsModalDialogHost());
286 }
287
288 SkColor SRTPromptDialog::GetDetailsButtonColor() {
289 return GetNativeTheme()->GetSystemColor(
290 ui::NativeTheme::kColorId_LinkEnabled);
291 }
292
293 void SRTPromptDialog::UpdateDetailsButton() {
294 details_button_->SetText(details_view_->visible()
295 ? controller_->GetHideDetailsLabel()
296 : controller_->GetShowDetailsLabel());
297 details_button_->SetImage(
298 views::Button::STATE_NORMAL,
299 details_view_->visible()
300 ? gfx::CreateVectorIcon(kCaretUpIcon, GetDetailsButtonColor())
301 : gfx::CreateVectorIcon(kCaretDownIcon, GetDetailsButtonColor()));
302 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/views/srt_prompt_dialog.h ('k') | chrome/browser/ui/views/srt_prompt_dialog_browsertest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698