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

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

Issue 12317109: Add a dialog for getting user consent in the echo redeem flow. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 10 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2013 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/echo_dialog_views_chromeos.h"
6
7 #include "grit/generated_resources.h"
8 #include "ui/base/l10n/l10n_util.h"
9 #include "ui/base/resource/resource_bundle.h"
10 #include "ui/base/text/text_elider.h"
11 #include "ui/views/controls/label.h"
12 #include "ui/views/controls/link.h"
13 #include "ui/views/controls/link_listener.h"
tfarina 2013/02/26 19:22:57 already included in the header file.
tbarzic 2013/02/26 19:34:55 Done.
14 #include "ui/views/layout/box_layout.h"
15 #include "ui/views/widget/widget.h"
16 #include "ui/views/window/dialog_client_view.h"
17
18 namespace {
19
20 const int kDialogContentWidth = 350;
21
22 const int kDialogContentTopInset = 20;
23 const int kDialogContentLeftInset = 20;
24 const int kDialogContentBottomInset = 20;
25 const int kDialogContentRightInset = 100;
26
27 const int kLinkLeftInset = 5;
28
29 // Dialog text has medium sized font.
30 gfx::Font GetDefaultFontForEcho() {
31 return ResourceBundle::GetSharedInstance().GetFont(
tfarina 2013/02/26 19:22:57 ui::ResourceBundle here too and elsewhere else you
tbarzic 2013/02/26 19:34:55 Done.
32 ui::ResourceBundle::MediumFont);
33 }
34
35 // Label that shows the service name label.
36 // The label should have underlined text and display tooltip on hover.
37 class EchoServiceNameLabel : public views::Label {
38 public:
39 EchoServiceNameLabel(const string16& label, const string16& tooltip)
40 : views::Label(label) {
41 SetTooltipText(tooltip);
42 SetMultiLine(false);
43 SetFont(GetDefaultFontForEcho().DeriveFont(0, gfx::Font::UNDERLINE));
44 }
45 virtual ~EchoServiceNameLabel() {}
46
47 // views::Label override.
48 // Label have HitTestRect return false by default. To be able to show a
49 // tooltip, this should be overriden.
50 virtual bool HitTestRect(const gfx::Rect& rect) const {
51 return GetLocalBounds().Intersects(rect);
52 }
53
54 private:
55 DISALLOW_COPY_AND_ASSIGN(EchoServiceNameLabel);
56 };
57
58 // A helper view that contains horizontal set of labels representing one row of
59 // the dialog text content. The number of labels is not limited, but their
60 // combined width will be smaller than |kDialogContentWidth|.
61 class EchoDialogContentRowView : public views::View {
62 public:
63 EchoDialogContentRowView() {
64 SetLayoutManager(
65 new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 0));
66 }
67
68 virtual ~EchoDialogContentRowView() {}
69
70 private:
71 DISALLOW_COPY_AND_ASSIGN(EchoDialogContentRowView);
72 };
73
74 // View representing text content of the dialog. It consists of set of
75 // vertically laid out |EchoDialogContentRowView| views with limited width. The
76 // rows are filled with text pieces that should be displayed using different
77 // styles.
78 class EchoDialogContentView : public views::View {
79 public:
80 explicit EchoDialogContentView(views::LinkListener* listener);
81 virtual ~EchoDialogContentView() {}
82
83 // Creates text pieces that represent the content shown in the dialog when
84 // echo extension is enabled to redeem offers.
85 //
86 // General layout of the dialog in this case is:
87 //
88 // --------------------------------------------------------------
89 // | ----------------- ---------------- ----------------- |
90 // | | normal text 1 | | service name | | normal text 2 | |
91 // | ----------------- ---------------- ----------------- |
92 // | ---------------------------------------------------------- |
93 // | | normal text 2 | |
94 // | ---------------------------------------------------------- |
95 // | ----------------- --------------------- |
96 // | | normal text 2 | | 'More info' link | |
97 // | ----------------- --------------------- |
98 // --------------------------------------------------------------
99 //
100 // Where 'normal text' is predetermined text of type TEXT_PIECE_LABEL,
101 // 'service name' equals |service_name| and is of type
102 // TEXT_PIECE_SERVICE_NAME_LABEL. Hovering over the 'service name' label will
103 // display tooltip whose content equals |origin|.
104 // Note that the labels may be broken up, preferably at word delimiters (this
105 // is not possible for words that are too long).
106 void InitializeForEnabledEcho(const string16& service_name,
107 const string16& origin);
108
109 // Creates text pieces that represent the content shown in the dialog when
110 // echo extension is not allowed to redeem offers.
111 //
112 // General layout of the dialog in this case is:
113 //
114 // --------------------------------------------------------------
115 // | ---------------------------------------------------------- |
116 // | | normal text 1 | |
117 // | ---------------------------------------------------------- |
118 // | ----------------- --------------------- |
119 // | | normal text 1 | | 'More info' link | |
120 // | ----------------- --------------------- |
121 // --------------------------------------------------------------
122 //
123 // With the same parts as for the enabled echo.
124 void InitializeForDisabledEcho();
125
126 // Creates layout with text pieces initialized in
127 // |InitializeFor{Disabled|Enabled}Echo|.
128 void SetupLayout();
129
130 private:
131 enum TextPieceType {
132 TEXT_PIECE_INVALID,
133 TEXT_PIECE_LABEL,
134 TEXT_PIECE_SERVICE_NAME_LABEL,
135 TEXT_PIECE_LINK
136 };
137
138 // Information about a text piece that should be shown in the dialog.
139 struct TextPieceInfo {
140 TextPieceInfo() : type(TEXT_PIECE_INVALID) {}
141 TextPieceInfo(const string16& label,
142 TextPieceType type)
143 : label(label),
144 type(type) {
145 }
146
147 string16 label;
148 TextPieceType type;
149 };
150
151 // Adds text piece described with |info| to the |current_row|.
152 // If the whole text piece doesn't fit in the row, the row is filled with as
153 // much of words from the text piece as possible. New row are created and
154 // filled with text pieces content until the whole text piece is added to the
155 // layout.
156 // Upon completion |current_row| will be set to the last added row.
157 void SetupTextPieceLayout(const TextPieceInfo& info,
158 EchoDialogContentRowView** current_row);
159 // Creates a label view for text piece of type |type| with content |text|.
160 // |at_row_start| is set if the text_piece would be the first text piece in
161 // the row. Links are added additional padding if they are not at the row
162 // start.
163 views::Label* CreateTextPieceView(TextPieceType type,
164 const string16& label,
165 bool at_row_start);
166
167 string16 service_origin_;
168 // Listener invoked when a label of type link is clicked.
169 views::LinkListener* link_listener_;
170 // Dialog content divided into pieces with different display stype.
171 std::vector<TextPieceInfo> text_pieces_;
172
173 DISALLOW_COPY_AND_ASSIGN(EchoDialogContentView);
174 };
175
176 EchoDialogContentView::EchoDialogContentView(views::LinkListener* link_listener)
177 : link_listener_(link_listener) {
178 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical, 0, 0 ,0));
179 }
180
181 void EchoDialogContentView::InitializeForEnabledEcho(
182 const string16& service_name,
183 const string16& origin) {
184 service_origin_ = origin;
185
186 size_t service_name_offset = 0;
187 string16 text = l10n_util::GetStringFUTF16(IDS_ECHO_CONSENT_DIALOG_TEXT,
188 service_name,
189 &service_name_offset);
190
191 text_pieces_.push_back(
192 TextPieceInfo(text.substr(0, service_name_offset), TEXT_PIECE_LABEL));
193 text_pieces_.push_back(
194 TextPieceInfo(service_name, TEXT_PIECE_SERVICE_NAME_LABEL));
195 text_pieces_.push_back(
196 TextPieceInfo(text.substr(service_name_offset + service_name.length()),
197 TEXT_PIECE_LABEL));
198 text_pieces_.push_back(TextPieceInfo(
199 l10n_util::GetStringUTF16(IDS_OFFERS_CONSENT_INFOBAR_LABEL_LEARN_MORE),
200 TEXT_PIECE_LINK));
201 }
202
203 void EchoDialogContentView::InitializeForDisabledEcho() {
204 text_pieces_.push_back(TextPieceInfo(
205 l10n_util::GetStringUTF16(IDS_ECHO_DISABLED_CONSENT_DIALOG_TEXT),
206 TEXT_PIECE_LABEL));
207 text_pieces_.push_back(TextPieceInfo(
208 l10n_util::GetStringUTF16(IDS_OFFERS_CONSENT_INFOBAR_LABEL_LEARN_MORE),
209 TEXT_PIECE_LINK));
210 }
211
212 void EchoDialogContentView::SetupLayout() {
213 EchoDialogContentRowView* current_row = new EchoDialogContentRowView();
214 AddChildView(current_row);
215 for (size_t i= 0; i < text_pieces_.size(); ++i)
216 SetupTextPieceLayout(text_pieces_[i], &current_row);
217
218 set_border(views::Border::CreateEmptyBorder(kDialogContentTopInset,
219 kDialogContentLeftInset,
220 kDialogContentBottomInset,
221 kDialogContentRightInset));
222 }
223
224 void EchoDialogContentView::SetupTextPieceLayout(
225 const TextPieceInfo& info,
226 EchoDialogContentRowView** current_row) {
227 if (info.label.empty())
228 return;
229
230 gfx::Size current_size = (*current_row)->GetPreferredSize();
231
232 scoped_ptr<views::Label> text_piece(
233 CreateTextPieceView(info.type, info.label, current_size.width() == 0));
234 gfx::Size text_piece_size = text_piece->GetPreferredSize();
235
236 // If the while label can fit in the free space in the current row, just add
237 // it and return.
238 if (text_piece_size.width() + current_size.width() < kDialogContentWidth) {
239 (*current_row)->AddChildView(text_piece.release());
240 return;
241 }
242
243 string16 residue = info.label;
244 gfx::Font text_piece_font = text_piece->font();
245 std::vector<string16> lines;
246
247 // Fill up the free space in the current row. |IGNORE_LONG_WORDS| is used to
248 // ensure words don't get broken in pieces. This step can be skipped if the
249 // current row is empty.
250 if (current_size.width() > 0) {
251 ui::ElideRectangleText(info.label, text_piece_font,
252 kDialogContentWidth - current_size.width(), text_piece_size.height(),
253 ui::IGNORE_LONG_WORDS, &lines);
254 if (!lines[0].empty()) {
255 text_piece->SetText(lines[0]);
256 (*current_row)->AddChildView(text_piece.release());
257
258 // Compute the part of the text piece that still has to be added to the
259 // view layout.
260 residue = info.label.substr(lines[0].length());
261 TrimWhitespace(residue, TRIM_LEADING, &residue);
262 }
263 }
264
265 // Brake up the rest of the text piece into lines shorter than
266 // |kEchoPromtWidth|, so they can fit in a single row. Use INT_MAX so the
267 // number of lines is not limited.
268 ui::ElideRectangleText(residue, text_piece_font, kDialogContentWidth, INT_MAX,
269 ui::WRAP_LONG_WORDS, &lines);
270
271 // Add lines one by one to the layout.
272 for (size_t i = 0; i < lines.size(); ++i) {
273 if ((*current_row)->GetPreferredSize().width() > 0) {
274 *current_row = new EchoDialogContentRowView();
275 AddChildView(*current_row);
276 }
277 (*current_row)->AddChildView(CreateTextPieceView(info.type, lines[i],
278 true));
279 }
280 }
281
282 views::Label* EchoDialogContentView::CreateTextPieceView(TextPieceType type,
283 const string16& text,
284 bool at_row_start) {
285 switch (type) {
286 case TEXT_PIECE_LABEL:
287 {
288 views::Label* label = new views::Label(text);
289 label->SetMultiLine(false);
290 label->SetFont(GetDefaultFontForEcho());
291 return label;
292 }
293 case TEXT_PIECE_SERVICE_NAME_LABEL:
294 return new EchoServiceNameLabel(text, service_origin_);
295 case TEXT_PIECE_LINK:
296 {
297 views::Link* link = new views::Link(text);
298 link->set_listener(link_listener_);
299 link->SetUnderline(false);
300 link->SetFont(GetDefaultFontForEcho());
301 if (!at_row_start) {
302 link->set_border(
303 views::Border::CreateEmptyBorder(0, kLinkLeftInset, 0, 0));
304 }
305 return link;
306 }
307 default:
308 NOTREACHED();
309 return NULL;
310 }
311 }
312
313 } // namespace
314
315 namespace views {
316
317 EchoDialogView::EchoDialogView(EchoDialog::Listener* listener)
318 : listener_(listener),
319 ok_button_label_id_(0),
320 cancel_button_label_id_(0) {
321 SetLayoutManager(
322 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0 ,0));
323 }
324
325 EchoDialogView::~EchoDialogView() {}
326
327 void EchoDialogView::InitForEnabledEcho(const string16& service_name,
328 const string16& origin) {
329 ok_button_label_id_ = IDS_OFFERS_CONSENT_INFOBAR_ENABLE_BUTTON;
330 cancel_button_label_id_ = IDS_OFFERS_CONSENT_INFOBAR_DISABLE_BUTTON;
331
332 EchoDialogContentView* dialog_content = new EchoDialogContentView(this);
333 dialog_content->InitializeForEnabledEcho(service_name, origin);
334 dialog_content->SetupLayout();
335
336 AddChildView(dialog_content);
337 }
338
339 void EchoDialogView::InitForDisabledEcho() {
340 ok_button_label_id_ = 0;
341 cancel_button_label_id_ = IDS_ECHO_CONSENT_DISMISS_BUTTON;
342
343 EchoDialogContentView* dialog_content = new EchoDialogContentView(this);
344 dialog_content->InitializeForDisabledEcho();
345 dialog_content->SetupLayout();
346
347 AddChildView(dialog_content);
348 }
349
350 void EchoDialogView::Show(gfx::NativeWindow parent) {
351 DCHECK(cancel_button_label_id_);
352
353 views::DialogDelegateView::CreateDialogWidget(this, parent, parent);
354 set_border(views::Border::CreateEmptyBorder(0, 0, 10, 0));
355 GetWidget()->Show();
356 }
357
358 int EchoDialogView::GetDefaultDialogButton() const {
359 return ui::DIALOG_BUTTON_NONE;
360 }
361
362 int EchoDialogView::GetDialogButtons() const {
363 int buttons = ui::DIALOG_BUTTON_NONE;
364 if (ok_button_label_id_)
365 buttons |= ui::DIALOG_BUTTON_OK;
366 if (cancel_button_label_id_)
367 buttons |= ui::DIALOG_BUTTON_CANCEL;
368 return buttons;
369 }
370
371 bool EchoDialogView::Accept() {
372 if (listener_) {
373 listener_->OnAccept();
374 listener_ = NULL;
375 }
376 return true;
377 }
378
379 bool EchoDialogView::Cancel() {
380 if (listener_) {
381 listener_->OnCancel();
382 listener_ = NULL;
383 }
384 return true;
385 }
386
387 string16 EchoDialogView::GetDialogButtonLabel(ui::DialogButton button) const {
388 if (button == ui::DIALOG_BUTTON_OK && ok_button_label_id_) {
tfarina 2013/02/26 19:22:57 no curlies on single line statements.
tbarzic 2013/02/26 19:34:55 Done.
389 return l10n_util::GetStringUTF16(ok_button_label_id_);
390 }
391 if (button == ui::DIALOG_BUTTON_CANCEL && cancel_button_label_id_)
392 return l10n_util::GetStringUTF16(cancel_button_label_id_);
393 return string16();
394 }
395
396 ui::ModalType EchoDialogView::GetModalType() const {
397 return ui::MODAL_TYPE_WINDOW;
398 }
399
400 bool EchoDialogView::ShouldShowWindowTitle() const {
401 return false;
402 }
403
404 bool EchoDialogView::ShouldShowWindowIcon() const {
405 return false;
406 }
407
408 void EchoDialogView::LinkClicked(views::Link* source, int event_flags) {
409 if (!listener_)
410 return;
411 listener_->OnMoreInfoLinkClicked();
412 }
413
414 } // namespace views
415
416 EchoDialog* EchoDialog::Create(EchoDialog::Listener* listener) {
417 return new views::EchoDialogView(listener);
418 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698