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

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: Addressed Fabio's comments 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/chrome_web_modal_dialog_manager_delegate.h"
14 #include "chrome/browser/ui/views/frame/browser_view.h"
15 #include "components/constrained_window/constrained_window_views.h"
16 #include "components/web_modal/web_contents_modal_dialog_host.h"
17 #include "ui/base/ui_base_types.h"
18 #include "ui/events/event.h"
19 #include "ui/gfx/geometry/size.h"
20 #include "ui/gfx/native_widget_types.h"
21 #include "ui/gfx/paint_vector_icon.h"
22 #include "ui/gfx/text_constants.h"
23 #include "ui/native_theme/native_theme.h"
24 #include "ui/views/controls/label.h"
25 #include "ui/views/controls/scroll_view.h"
26 #include "ui/views/controls/separator.h"
27 #include "ui/views/layout/box_layout.h"
28 #include "ui/views/layout/grid_layout.h"
29 #include "ui/views/layout/layout_constants.h"
30 #include "ui/views/widget/widget.h"
31
32 namespace safe_browsing {
33
34 // static
35 void SRTPromptController::ShowSRTPrompt(Browser* browser,
36 SRTPromptController* controller) {
37 SRTPromptDialog* dialog = new SRTPromptDialog(controller);
38 dialog->Show(browser);
39 }
40
41 } // namespace safe_browsing
42
43 namespace {
44
45 using LabelInfo = safe_browsing::SRTPromptController::LabelInfo;
46
47 constexpr int kDialogWidth = 448;
48 constexpr int kDetailsSectionMaxHeight = 150;
49 constexpr int kBulletColumnWidth = 10;
50 // Constants used for the layout of the label views.
51 static constexpr int kMainColumSetId = 0;
sky 2017/04/05 21:17:42 Be consistent. No need for the static here.
alito 2017/04/06 00:20:22 Done.
52 static constexpr int kBulletColumnSetId = 1;
53
54 // Returns a view containing |item| with insets defined by |top|, |left|,
55 // |bottom|, and |right|.
56 views::View* CreateViewWithInsets(views::View* item,
57 int top,
58 int left,
59 int bottom,
60 int right) {
61 views::View* view = new views::View();
62 views::GridLayout* layout = new views::GridLayout(view);
63 view->SetLayoutManager(layout);
64 layout->SetInsets(top, left, bottom, right);
65 layout->AddColumnSet(0)->AddColumn(
sky 2017/04/05 21:17:42 GridLayout seems like overkill here. Isn't this th
alito 2017/04/06 00:20:22 Indeed. I had tried adding an empty border to the
66 views::GridLayout::LEADING, views::GridLayout::LEADING,
67 /*resize_percent=*/1, views::GridLayout::USE_PREF,
68 /*fixed_width=*/0,
69 /*min_width=*/0);
70 layout->StartRow(0, 0);
71 layout->AddView(item);
72
73 return view;
74 }
75
76 // Helper function used by |CreateLabelView()| below that adds |labels| to
77 // |label_view|.
78 void AddLabelsToLabelView(views::View* label_view,
79 views::GridLayout* layout,
80 const std::vector<LabelInfo>& labels) {
81 static constexpr base::char16 kBulletPoint[] = {0x2022, 0};
82
83 bool first_label = true;
84 bool last_label_was_bullet = false;
85 for (const LabelInfo& label_info : labels) {
86 const bool is_bullet = label_info.type == LabelInfo::BULLET_ITEM;
87 views::Label* label = new views::Label(label_info.text);
88 label->SetMultiLine(true);
89 label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
90
91 // Do not add a padding row if
92 // - this is the first label being added, or
93 // - a bullet item is being added and the last label was also a bullet item.
94 bool skip_padding = first_label || (is_bullet && last_label_was_bullet);
95 if (!skip_padding)
96 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
97
98 layout->StartRow(0, is_bullet ? kBulletColumnSetId : kMainColumSetId);
99 if (is_bullet) {
100 views::Label* bullet = new views::Label(base::string16(kBulletPoint));
101 layout->AddView(bullet);
102 }
103 layout->AddView(label);
104
105 last_label_was_bullet = is_bullet;
106 first_label = false;
107 }
108 }
109
110 // Creates a view that displays two types of labels: multiline labels
111 // representing whole paragraphs or indented labels that are start with a bullet
112 // point.
113 //
114 // A vertical padding of size |top_vertical_space| is added before the labels.
115 views::View* CreateLabelView(int top_vertical_space,
116 const std::vector<LabelInfo>& labels) {
117 views::View* label_view = new views::View();
118 views::GridLayout* layout = new views::GridLayout(label_view);
119 layout->SetInsets(0, views::kButtonHEdgeMarginNew, 0,
120 views::kButtonHEdgeMarginNew);
121
122 label_view->SetLayoutManager(layout);
123
124 views::ColumnSet* main_column_set = layout->AddColumnSet(kMainColumSetId);
125 main_column_set->AddColumn(views::GridLayout::FILL,
126 views::GridLayout::LEADING,
127 /*resize_percent=*/1, views::GridLayout::USE_PREF,
128 /*fixed_width=*/0,
129 /*min_width=*/0);
130
131 views::ColumnSet* bullet_column_set_ =
132 layout->AddColumnSet(kBulletColumnSetId);
133 bullet_column_set_->AddPaddingColumn(
134 /*resize_percent=*/0, views::kUnrelatedControlLargeHorizontalSpacing);
135 bullet_column_set_->AddColumn(
136 views::GridLayout::FILL, views::GridLayout::LEADING,
137 /*resize_percent=*/0, views::GridLayout::USE_PREF,
138 /*fixed_width=*/0,
139 /*min_width=*/0);
140 bullet_column_set_->AddPaddingColumn(/*resize_percent=*/0,
141 kBulletColumnWidth);
142 bullet_column_set_->AddColumn(
143 views::GridLayout::FILL, views::GridLayout::LEADING,
144 /*resize_percent=*/1, views::GridLayout::USE_PREF,
145 /*fixed_width=*/0,
146 /*min_width=*/0);
147
148 if (top_vertical_space > 0)
149 layout->AddPaddingRow(/*vertical_resize=*/0, top_vertical_space);
150
151 AddLabelsToLabelView(label_view, layout, labels);
152
153 layout->AddPaddingRow(/*vertical_resize=*/0,
154 views::kUnrelatedControlLargeHorizontalSpacing);
155 return label_view;
156 }
157
158 } // namespace
159
160 ////////////////////////////////////////////////////////////////////////////////
161 // SRTPromptDialog::ExpandableMessageView
162 //
163 // A view, whose visibilty can be toggled, and will be used for the details
164 // section the main dialog.
165 class SRTPromptDialog::ExpandableMessageView : public views::View {
sky 2017/04/05 21:17:42 It seems like you're subclassing here for convenie
alito 2017/04/06 00:20:22 I plan to add animation to the expansion and foldi
sky 2017/04/06 02:10:02 It's easy to add it back when you get there, vs on
alito 2017/04/06 03:37:46 Fair enough. I've changed this to populate the det
166 public:
167 explicit ExpandableMessageView(const std::vector<LabelInfo>& labels);
168 ~ExpandableMessageView() override;
169
170 void ToggleShowView();
171
172 // views::View overrides.
173 gfx::Size GetPreferredSize() const override;
174 int GetHeightForWidth(int width) const override;
175
176 private:
177 DISALLOW_COPY_AND_ASSIGN(ExpandableMessageView);
178 };
179
180 SRTPromptDialog::ExpandableMessageView::ExpandableMessageView(
181 const std::vector<LabelInfo>& labels) {
182 views::GridLayout* layout = new views::GridLayout(this);
183 SetLayoutManager(layout);
184
185 SetVisible(false);
186
187 constexpr int kColumnId = 0;
188 views::ColumnSet* column_set = layout->AddColumnSet(kColumnId);
189 column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::LEADING,
190 /*resize_percent=*/1, views::GridLayout::USE_PREF,
191 /*fixed_width=*/0,
192 /*min_width=*/0);
193
194 // Add the main message view inside a scroll view.
195 views::View* label_view =
196 CreateLabelView(views::kUnrelatedControlLargeHorizontalSpacing, labels);
197 views::ScrollView* scroll_view = new views::ScrollView();
198 scroll_view->ClipHeightTo(/*min_height=*/0, kDetailsSectionMaxHeight);
199 scroll_view->SetContents(label_view);
200 layout->StartRow(0, kColumnId);
201 layout->AddView(scroll_view);
202 }
203
204 SRTPromptDialog::ExpandableMessageView::~ExpandableMessageView() {}
205
206 void SRTPromptDialog::ExpandableMessageView::ToggleShowView() {
207 SetVisible(!visible());
208 PreferredSizeChanged();
209 }
210
211 gfx::Size SRTPromptDialog::ExpandableMessageView::GetPreferredSize() const {
212 gfx::Size size = views::View::GetPreferredSize();
213 return gfx::Size(size.width(), visible() ? size.height() : 0);
214 }
215
216 int SRTPromptDialog::ExpandableMessageView::GetHeightForWidth(int width) const {
217 return GetPreferredSize().height();
218 }
219
220 ////////////////////////////////////////////////////////////////////////////////
221 // SRTPromptDialog
222
223 SRTPromptDialog::SRTPromptDialog(safe_browsing::SRTPromptController* controller)
224 : browser_(nullptr),
225 controller_(controller),
226 interaction_done_(false),
227 details_view_(nullptr),
228 expand_details_button_(nullptr),
229 expand_details_button_color_(GetNativeTheme()->GetSystemColor(
sky 2017/04/05 21:17:42 This variables is only used in this function. No n
alito 2017/04/06 00:20:22 A private member function now returns the color (a
230 ui::NativeTheme::kColorId_LinkEnabled)),
231 expand_icon_(
sky 2017/04/05 21:17:42 Why do you need to cache these icons? Can you look
alito 2017/04/06 00:20:22 Changed to look them up as needed.
232 gfx::CreateVectorIcon(kCaretDownIcon, expand_details_button_color_)),
233 fold_icon_(
234 gfx::CreateVectorIcon(kCaretUpIcon, expand_details_button_color_)) {
235 DCHECK(controller_);
236
237 SetLayoutManager(new views::BoxLayout(
238 /*orientation=*/views::BoxLayout::kVertical,
239 /*inside_border_horizontal_spacing=*/0,
240 /*inside_border_vertical_spacing=*/views::kPanelVertMargin,
241 /*between_child_spacing=*/0));
242
243 AddChildView(CreateLabelView(0, controller_->GetMainText()));
244 AddChildView(new views::Separator());
245
246 details_view_ = new ExpandableMessageView(controller_->GetDetailsText());
247 AddChildView(details_view_);
248
249 expand_details_button_ =
250 new views::LabelButton(this, controller_->GetShowDetailsLabel());
251 expand_details_button_->SetEnabledTextColors(expand_details_button_color_);
252 expand_details_button_->SetImage(
253 views::Button::STATE_NORMAL,
254 details_view_->visible() ? fold_icon_ : expand_icon_);
255 AddChildView(CreateViewWithInsets(
256 expand_details_button_, views::kPanelVertMargin,
257 views::kButtonHEdgeMarginNew, views::kPanelVertMargin,
258 views::kButtonHEdgeMarginNew));
259 AddChildView(new views::Separator());
260 }
261
262 SRTPromptDialog::~SRTPromptDialog() {
263 // Make sure the controller is correctly notified in case the dialog widget is
264 // closed by some other means than the dialog buttons.
265 Close();
sky 2017/04/05 21:17:42 This class is owned by the widget and deleted when
alito 2017/04/06 00:20:22 This call ensures that the controller is notified
sky 2017/04/06 02:10:02 It's better to be explicit rather than relying on
alito 2017/04/06 03:37:46 Changed to explicitly notify the controller if nee
266 }
267
268 void SRTPromptDialog::Show(Browser* browser) {
269 DCHECK(browser);
sky 2017/04/05 21:17:42 DCHECK(!browser_)?
alito 2017/04/06 00:20:22 Done.
270
271 browser_ = browser;
272 BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser_);
sky 2017/04/05 21:17:42 Why do you need to get the BrowserView for browser
alito 2017/04/06 00:20:22 Ah! That's a shortcut I hadn't noticed.
273 constrained_window::CreateBrowserModalDialogViews(
274 this, browser_view->GetNativeWindow())
275 ->Show();
276 controller_->DialogShown();
277 }
278
279 // DialogModel overrides.
280
281 bool SRTPromptDialog::ShouldDefaultButtonBeBlue() const {
282 return true;
283 }
284
285 // WidgetDelegate overrides.
286
287 ui::ModalType SRTPromptDialog::GetModalType() const {
288 return ui::MODAL_TYPE_WINDOW;
289 }
290
291 base::string16 SRTPromptDialog::GetWindowTitle() const {
292 return controller_->GetWindowTitle();
293 }
294
295 // DialogDelegate overrides.
296
297 base::string16 SRTPromptDialog::GetDialogButtonLabel(
298 ui::DialogButton button) const {
299 DCHECK(button == ui::DIALOG_BUTTON_OK || button == ui::DIALOG_BUTTON_CANCEL);
300
301 if (button == ui::DIALOG_BUTTON_OK)
302 return controller_->GetAcceptButtonLabel();
303 return DialogDelegate::GetDialogButtonLabel(button);
304 }
305
306 bool SRTPromptDialog::Accept() {
307 if (!interaction_done_) {
308 interaction_done_ = true;
309 controller_->Accept();
310 }
311 return true;
312 }
313
314 bool SRTPromptDialog::Cancel() {
315 if (!interaction_done_) {
sky 2017/04/05 21:17:42 If the underlying widget is destroyed outside of c
alito 2017/04/06 00:20:22 This is already handled in the destructor, which c
sky 2017/04/06 02:10:02 Acknowledged.
316 interaction_done_ = true;
317 controller_->Cancel();
318 }
319 return true;
320 }
321
322 // View overrides.
323
324 gfx::Size SRTPromptDialog::GetPreferredSize() const {
325 return gfx::Size(kDialogWidth, GetHeightForWidth(kDialogWidth));
326 }
327
328 // views::ButtonListener overrides.
329
330 void SRTPromptDialog::ButtonPressed(views::Button* sender,
331 const ui::Event& event) {
332 DCHECK_EQ(sender, expand_details_button_);
333 DCHECK(browser_);
334
335 details_view_->ToggleShowView();
336 expand_details_button_->SetText(details_view_->visible()
337 ? controller_->GetHideDetailsLabel()
338 : controller_->GetShowDetailsLabel());
339 expand_details_button_->SetImage(
340 views::Button::STATE_NORMAL,
341 details_view_->visible() ? fold_icon_ : expand_icon_);
342
343 ChromeWebModalDialogManagerDelegate* manager = browser_;
344 constrained_window::UpdateWidgetModalDialogPosition(
345 GetWidget(), manager->GetWebContentsModalDialogHost());
346 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698