Chromium Code Reviews| OLD | NEW |
|---|---|
| (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], ¤t_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 } | |
| OLD | NEW |