OLD | NEW |
---|---|
(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/settings_reset_prompt_dialog.h" | |
6 | |
7 #include "chrome/browser/safe_browsing/settings_reset_prompt/settings_reset_prom pt_controller.h" | |
8 #include "chrome/browser/ui/browser.h" | |
9 #include "chrome/browser/ui/chrome_web_modal_dialog_manager_delegate.h" | |
10 #include "chrome/browser/ui/views/frame/browser_view.h" | |
11 #include "chrome/browser/ui/views/toolbar/app_menu_button.h" | |
12 #include "chrome/browser/ui/views/toolbar/toolbar_view.h" | |
13 #include "components/constrained_window/constrained_window_views.h" | |
14 #include "components/web_modal/web_contents_modal_dialog_host.h" | |
15 #include "ui/gfx/color_palette.h" | |
16 #include "ui/gfx/image/image.h" | |
17 #include "ui/gfx/paint_vector_icon.h" | |
18 #include "ui/gfx/text_constants.h" | |
19 #include "ui/gfx/vector_icons_public.h" | |
20 #include "ui/views/bubble/bubble_border.h" | |
21 #include "ui/views/controls/label.h" | |
22 #include "ui/views/controls/link.h" | |
23 #include "ui/views/controls/scroll_view.h" | |
24 #include "ui/views/controls/separator.h" | |
25 #include "ui/views/layout/box_layout.h" | |
26 #include "ui/views/layout/grid_layout.h" | |
27 #include "ui/views/layout/layout_constants.h" | |
28 #include "ui/views/view.h" | |
29 #include "ui/views/widget/widget.h" | |
30 | |
31 namespace safe_browsing { | |
32 | |
33 // static | |
34 void SettingsResetPromptController::ShowSettingsResetPrompt( | |
35 Browser* browser, | |
36 SettingsResetPromptController* controller) { | |
37 SettingsResetPromptDialog* dialog = new SettingsResetPromptDialog(controller); | |
38 // The dialog will delete itself, as implemented in | |
39 // |DialogDelegateView::DeleteDelegate()|, when its widget is closed. | |
40 dialog->Show(browser); | |
41 } | |
42 | |
43 } // namespace safe_browsing | |
44 | |
45 namespace { | |
46 | |
47 constexpr int kDialogWidth = 512; | |
48 constexpr int kDetailsSectionMaxHeight = 150; | |
49 constexpr int kBulletColumnWidth = 5; | |
50 | |
51 //////////////////////////////////////////////////////////////////////////////// | |
52 // SimpleMessageView | |
53 // | |
54 // A simple view that displays two types of labels: multiline labels or indented | |
55 // single-line labels that are indented and start with a bullet point. The | |
56 // indented text is intended to be used to display setting values (URLs) and is | |
57 // elided if the text is too wide to fit in its entirety. | |
58 class SimpleMessageView : public views::View { | |
sky
2017/02/23 04:27:31
Do you really need a view subclass here? It seems
alito
2017/02/23 05:37:08
SimpleMessageView is used both in the main dialog
sky
2017/02/23 18:44:52
My main concern here is your are subclassing but n
alito
2017/02/24 00:19:09
Ah, I see your point. Makes sense not to subclass
| |
59 public: | |
60 explicit SimpleMessageView(int top_vertical_spacing); | |
61 ~SimpleMessageView() override; | |
62 | |
63 void AddLabel(const safe_browsing::SettingsResetPromptController::LabelInfo& | |
64 label_info); | |
65 | |
66 private: | |
67 static constexpr int kMainColumSetId = 0; | |
68 static constexpr int kBulletColumnSetId = 1; | |
69 | |
70 views::GridLayout* layout_; | |
71 bool first_label_; | |
72 bool last_label_was_bullet_; | |
73 | |
74 DISALLOW_COPY_AND_ASSIGN(SimpleMessageView); | |
75 }; | |
76 | |
77 SimpleMessageView::SimpleMessageView(int top_vertical_spacing) | |
78 : layout_(new views::GridLayout(this)), | |
79 first_label_(true), | |
80 last_label_was_bullet_(false) { | |
81 SetLayoutManager(layout_); | |
82 | |
83 views::ColumnSet* main_column_set = layout_->AddColumnSet(kMainColumSetId); | |
84 main_column_set->AddColumn(views::GridLayout::FILL, | |
85 views::GridLayout::LEADING, | |
86 /*resize_percent=*/1, views::GridLayout::USE_PREF, | |
87 /*fixed_width=*/0, | |
88 /*min_width=*/0); | |
89 | |
90 views::ColumnSet* bullet_column_set_ = | |
91 layout_->AddColumnSet(kBulletColumnSetId); | |
92 bullet_column_set_->AddPaddingColumn( | |
93 /*resize_percent=*/0, views::kUnrelatedControlLargeHorizontalSpacing); | |
94 bullet_column_set_->AddColumn( | |
95 views::GridLayout::FILL, views::GridLayout::LEADING, | |
96 /*resize_percent=*/0, views::GridLayout::USE_PREF, | |
97 /*fixed_width=*/0, | |
98 /*min_width=*/0); | |
99 bullet_column_set_->AddPaddingColumn(/*resize_percent=*/0, | |
100 kBulletColumnWidth); | |
101 bullet_column_set_->AddColumn( | |
102 views::GridLayout::FILL, views::GridLayout::LEADING, | |
103 /*resize_percent=*/1, views::GridLayout::USE_PREF, | |
104 /*fixed_width=*/0, | |
105 /*min_width=*/0); | |
106 | |
107 if (top_vertical_spacing > 0) | |
108 layout_->AddPaddingRow(/*vertical_resize=*/0, top_vertical_spacing); | |
109 } | |
110 | |
111 SimpleMessageView::~SimpleMessageView() {} | |
112 | |
113 void SimpleMessageView::AddLabel( | |
114 const safe_browsing::SettingsResetPromptController::LabelInfo& label_info) { | |
115 static const base::char16 kBulletPoint[] = {0x2022, 0}; | |
116 | |
117 const bool is_bullet = | |
118 label_info.type == | |
119 safe_browsing::SettingsResetPromptController::LabelInfo::BULLET_ITEM; | |
120 views::Label* label = new views::Label(label_info.text); | |
121 label->SetHorizontalAlignment(gfx::ALIGN_LEFT); | |
122 if (is_bullet) { | |
123 label->SetElideBehavior(gfx::ELIDE_TAIL); | |
124 } else { | |
125 label->SetMultiLine(true); | |
126 } | |
127 | |
128 // Do not add a padding row if | |
129 // - this is the first label being added, or | |
130 // - a bullet item is being added and the last label was also a bullet item. | |
131 if (!(first_label_ || (is_bullet && last_label_was_bullet_))) | |
132 layout_->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); | |
133 | |
134 layout_->StartRow(0, is_bullet ? kBulletColumnSetId : kMainColumSetId); | |
135 if (is_bullet) { | |
136 views::Label* bullet = new views::Label(base::string16(kBulletPoint)); | |
137 layout_->AddView(bullet); | |
138 } | |
139 layout_->AddView(label); | |
140 | |
141 last_label_was_bullet_ = is_bullet; | |
142 first_label_ = false; | |
143 } | |
144 | |
145 } // namespace | |
146 | |
147 //////////////////////////////////////////////////////////////////////////////// | |
148 // SettingsResetPromptDialog::ExpandableMessageView | |
149 // | |
150 // A view, whose visibilty can be toggled, and will be used for the details | |
151 // section the main dialog. | |
152 class SettingsResetPromptDialog::ExpandableMessageView : public views::View { | |
153 public: | |
154 ExpandableMessageView(); | |
155 ~ExpandableMessageView() override; | |
156 | |
157 void AddLabel(const safe_browsing::SettingsResetPromptController::LabelInfo& | |
158 label_info); | |
159 void ToggleShowView(); | |
160 bool visible() const; | |
161 gfx::Size GetPreferredSize() const override; | |
sky
2017/02/23 04:27:31
Prefix with where overrides come from.
alito
2017/02/23 05:37:08
Done.
| |
162 int GetHeightForWidth(int width) const override; | |
163 | |
164 private: | |
165 SimpleMessageView* message_view_; | |
166 bool visible_; | |
167 | |
168 DISALLOW_COPY_AND_ASSIGN(ExpandableMessageView); | |
169 }; | |
170 | |
171 SettingsResetPromptDialog::ExpandableMessageView::ExpandableMessageView() | |
172 : visible_(false) { | |
sky
2017/02/23 04:27:31
This is mildly confusing given View also has a Set
alito
2017/02/23 05:37:08
Done.
| |
173 views::GridLayout* layout = new views::GridLayout(this); | |
174 SetLayoutManager(layout); | |
175 | |
176 constexpr int kColumnId = 0; | |
177 views::ColumnSet* column_set = layout->AddColumnSet(kColumnId); | |
178 column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::LEADING, | |
179 /*resize_percent=*/1, views::GridLayout::USE_PREF, | |
180 /*fixed_width=*/0, | |
181 /*min_width=*/0); | |
182 | |
183 // Add a horizontal line separator. | |
184 layout->StartRowWithPadding( | |
185 /*vertical_resize=*/0, kColumnId, | |
186 /*padding_resize=*/0, views::kUnrelatedControlVerticalSpacing); | |
187 layout->AddView(new views::Separator()); | |
188 | |
189 // Add the main message view inside a scroll view. | |
190 message_view_ = | |
191 new SimpleMessageView(views::kUnrelatedControlVerticalSpacing); | |
sky
2017/02/23 04:27:31
Move to member initializer list.
alito
2017/02/23 05:37:08
Done.
| |
192 views::ScrollView* scroll_view = new views::ScrollView(); | |
193 scroll_view->ClipHeightTo(/*min_height=*/0, kDetailsSectionMaxHeight); | |
194 scroll_view->SetContents(message_view_); | |
195 layout->StartRow(0, kColumnId); | |
196 layout->AddView(scroll_view); | |
197 } | |
198 | |
199 SettingsResetPromptDialog::ExpandableMessageView::~ExpandableMessageView() {} | |
200 | |
201 void SettingsResetPromptDialog::ExpandableMessageView::AddLabel( | |
202 const safe_browsing::SettingsResetPromptController::LabelInfo& label_info) { | |
203 message_view_->AddLabel(label_info); | |
204 } | |
205 | |
206 void SettingsResetPromptDialog::ExpandableMessageView::ToggleShowView() { | |
207 visible_ = !visible_; | |
208 PreferredSizeChanged(); | |
209 } | |
210 | |
211 bool SettingsResetPromptDialog::ExpandableMessageView::visible() const { | |
212 return visible_; | |
213 } | |
214 | |
215 gfx::Size SettingsResetPromptDialog::ExpandableMessageView::GetPreferredSize() | |
216 const { | |
217 gfx::Size size = views::View::GetPreferredSize(); | |
218 return gfx::Size(size.width(), visible_ ? size.height() : 0); | |
219 } | |
220 | |
221 int SettingsResetPromptDialog::ExpandableMessageView::GetHeightForWidth( | |
222 int width) const { | |
223 return GetPreferredSize().height(); | |
224 } | |
225 | |
226 //////////////////////////////////////////////////////////////////////////////// | |
227 // SettingsResetPromptDialog | |
228 | |
229 SettingsResetPromptDialog::SettingsResetPromptDialog( | |
230 safe_browsing::SettingsResetPromptController* controller) | |
231 : browser_(nullptr), | |
232 controller_(controller), | |
233 details_link_(nullptr), | |
234 interaction_done_(false) { | |
235 DCHECK(controller_); | |
236 | |
237 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical, | |
238 views::kButtonHEdgeMarginNew, | |
239 views::kPanelVertMargin, 0)); | |
240 | |
241 // Add the dialog's main message view. | |
242 SimpleMessageView* message_view = new SimpleMessageView(0); | |
243 for (const auto& label_info : controller_->GetMainText()) | |
244 message_view->AddLabel(label_info); | |
245 AddChildView(message_view); | |
246 | |
247 // Add the main details view that starts off not being visible. | |
248 details_view_ = new ExpandableMessageView(); | |
249 for (const auto& label_info : controller_->GetDetailsText()) | |
250 details_view_->AddLabel(label_info); | |
251 AddChildView(details_view_); | |
252 } | |
253 | |
254 SettingsResetPromptDialog::~SettingsResetPromptDialog() { | |
255 // Make sure the controller is correctly notified in case the dialog widget is | |
256 // closed by some other means than the dialog buttons. | |
257 Close(); | |
258 } | |
259 | |
260 void SettingsResetPromptDialog::Show(Browser* browser) { | |
261 DCHECK(browser); | |
262 browser_ = browser; | |
263 BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser); | |
264 constrained_window::CreateBrowserModalDialogViews( | |
265 this, browser_view->GetNativeWindow()) | |
266 ->Show(); | |
267 } | |
268 | |
269 // WidgetDelegate overrides. | |
270 | |
271 ui::ModalType SettingsResetPromptDialog::GetModalType() const { | |
272 return ui::MODAL_TYPE_WINDOW; | |
273 } | |
274 | |
275 bool SettingsResetPromptDialog::ShouldShowWindowIcon() const { | |
276 return true; | |
277 } | |
278 | |
279 gfx::ImageSkia SettingsResetPromptDialog::GetWindowIcon() { | |
280 return gfx::CreateVectorIcon(gfx::VectorIconId::WARNING, 32 /* Icon size. */, | |
281 gfx::kGoogleRed700); | |
282 } | |
283 | |
284 base::string16 SettingsResetPromptDialog::GetWindowTitle() const { | |
285 return controller_->GetWindowTitle(); | |
286 } | |
287 | |
288 // DialogModel overrides. | |
289 | |
290 int SettingsResetPromptDialog::GetDialogButtons() const { | |
291 return ui::DIALOG_BUTTON_OK; | |
292 } | |
293 | |
294 bool SettingsResetPromptDialog::ShouldDefaultButtonBeBlue() const { | |
295 return true; | |
296 } | |
297 | |
298 // DialogDelegate overrides. | |
299 | |
300 base::string16 SettingsResetPromptDialog::GetDialogButtonLabel( | |
301 ui::DialogButton button) const { | |
302 DCHECK_EQ(button, ui::DIALOG_BUTTON_OK); | |
303 return controller_->GetButtonLabel(); | |
304 } | |
305 | |
306 views::View* SettingsResetPromptDialog::CreateExtraView() { | |
307 // Add a "show details" link that toggles visibility of the details view. | |
308 details_link_ = new views::Link(controller_->GetShowDetailsLabel()); | |
309 details_link_->SetUnderline(false); | |
310 details_link_->set_listener(this); | |
311 return details_link_; | |
312 } | |
313 | |
314 bool SettingsResetPromptDialog::Accept() { | |
315 if (!interaction_done_) { | |
316 interaction_done_ = true; | |
317 controller_->Accept(); | |
318 } | |
319 return true; | |
320 } | |
321 | |
322 bool SettingsResetPromptDialog::Cancel() { | |
323 if (!interaction_done_) { | |
324 interaction_done_ = true; | |
325 controller_->Cancel(); | |
326 } | |
327 return true; | |
328 } | |
329 | |
330 bool SettingsResetPromptDialog::Close() { | |
331 return Cancel(); | |
332 } | |
333 | |
334 // View overrides. | |
335 | |
336 gfx::Size SettingsResetPromptDialog::GetPreferredSize() const { | |
337 return gfx::Size(kDialogWidth, GetHeightForWidth(kDialogWidth)); | |
338 } | |
339 | |
340 // LinkListener overrides. | |
341 | |
342 void SettingsResetPromptDialog::LinkClicked(views::Link* source, | |
343 int event_flags) { | |
344 DCHECK_EQ(source, details_link_); | |
345 DCHECK(browser_); | |
346 | |
347 details_view_->ToggleShowView(); | |
348 details_link_->SetText(details_view_->visible() | |
349 ? controller_->GetHideDetailsLabel() | |
350 : controller_->GetShowDetailsLabel()); | |
351 | |
352 ChromeWebModalDialogManagerDelegate* manager = browser_; | |
353 constrained_window::UpdateWidgetModalDialogPosition( | |
354 GetWidget(), manager->GetWebContentsModalDialogHost()); | |
355 } | |
OLD | NEW |