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

Unified 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: forgot to add echo_dialog_listener file 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/ui/views/echo_dialog_views_chromeos.cc
diff --git a/chrome/browser/ui/views/echo_dialog_views_chromeos.cc b/chrome/browser/ui/views/echo_dialog_views_chromeos.cc
new file mode 100644
index 0000000000000000000000000000000000000000..2ff62c47c50a59ae02d706f1d30eee7f651c1f1d
--- /dev/null
+++ b/chrome/browser/ui/views/echo_dialog_views_chromeos.cc
@@ -0,0 +1,413 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/views/echo_dialog_views_chromeos.h"
+
+#include "chrome/browser/ui/echo_dialog_listener_chromeos.h"
+#include "grit/generated_resources.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/base/resource/resource_bundle.h"
+#include "ui/base/text/text_elider.h"
+#include "ui/views/controls/label.h"
+#include "ui/views/controls/link.h"
+#include "ui/views/layout/box_layout.h"
+#include "ui/views/widget/widget.h"
+#include "ui/views/window/dialog_client_view.h"
+
+namespace {
+
+const int kDialogContentWidth = 350;
+
+const int kDialogContentTopInset = 20;
+const int kDialogContentLeftInset = 20;
+const int kDialogContentBottomInset = 20;
+const int kDialogContentRightInset = 100;
+
+const int kLinkLeftInset = 5;
+
+// Dialog text has medium sized font.
+gfx::Font GetDefaultFontForEcho() {
+ return ui::ResourceBundle::GetSharedInstance().GetFont(
+ ui::ResourceBundle::MediumFont);
+}
+
+// Label that shows the service name label.
+// The label should have underlined text and display tooltip on hover.
+class EchoServiceNameLabel : public views::Label {
+ public:
+ EchoServiceNameLabel(const string16& label, const string16& tooltip)
+ : views::Label(label) {
+ SetTooltipText(tooltip);
+ SetMultiLine(false);
+ SetFont(GetDefaultFontForEcho().DeriveFont(0, gfx::Font::UNDERLINE));
+ }
+ virtual ~EchoServiceNameLabel() {}
+
+ // views::Label override.
+ // Label have HitTestRect return false by default. To be able to show a
+ // tooltip, this should be overriden.
+ virtual bool HitTestRect(const gfx::Rect& rect) const {
sky 2013/02/26 21:28:48 This is a bug in Label, it should be fixed there.
tbarzic 2013/02/26 23:08:50 ok, I'll upload a cl to fix this in label
tbarzic 2013/03/18 18:21:58 Done.
+ return GetLocalBounds().Intersects(rect);
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(EchoServiceNameLabel);
+};
+
+// A helper view that contains horizontal set of labels representing one row of
+// the dialog text content. The number of labels is not limited, but their
+// combined width will be smaller than |kDialogContentWidth|.
+class EchoDialogContentRowView : public views::View {
+ public:
+ EchoDialogContentRowView() {
+ SetLayoutManager(
+ new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 0));
+ }
+
+ virtual ~EchoDialogContentRowView() {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(EchoDialogContentRowView);
+};
+
+// View representing text content of the dialog. It consists of set of
+// vertically laid out |EchoDialogContentRowView| views with limited width. The
+// rows are filled with text pieces that should be displayed using different
+// styles.
+class EchoDialogContentView : public views::View {
sky 2013/02/26 21:28:48 Is there a reason not to use label directly? If yo
tbarzic 2013/02/26 23:08:50 It's also the label types are different: only part
sky 2013/02/27 00:38:35 2013/02/26 23:08:50, tbarzic wrote:
+ public:
+ explicit EchoDialogContentView(views::LinkListener* listener);
+ virtual ~EchoDialogContentView() {}
+
+ // Creates text pieces that represent the content shown in the dialog when
+ // echo extension is enabled to redeem offers.
+ //
+ // General layout of the dialog in this case is:
+ //
+ // --------------------------------------------------------------
+ // | ----------------- ---------------- ----------------- |
+ // | | normal text 1 | | service name | | normal text 2 | |
+ // | ----------------- ---------------- ----------------- |
+ // | ---------------------------------------------------------- |
+ // | | normal text 2 | |
+ // | ---------------------------------------------------------- |
+ // | ----------------- --------------------- |
+ // | | normal text 2 | | 'More info' link | |
+ // | ----------------- --------------------- |
+ // --------------------------------------------------------------
+ //
+ // Where 'normal text' is predetermined text of type TEXT_PIECE_LABEL,
+ // 'service name' equals |service_name| and is of type
+ // TEXT_PIECE_SERVICE_NAME_LABEL. Hovering over the 'service name' label will
+ // display tooltip whose content equals |origin|.
+ // Note that the labels may be broken up, preferably at word delimiters (this
+ // is not possible for words that are too long).
+ void InitializeForEnabledEcho(const string16& service_name,
+ const string16& origin);
+
+ // Creates text pieces that represent the content shown in the dialog when
+ // echo extension is not allowed to redeem offers.
+ //
+ // General layout of the dialog in this case is:
+ //
+ // --------------------------------------------------------------
+ // | ---------------------------------------------------------- |
+ // | | normal text 1 | |
+ // | ---------------------------------------------------------- |
+ // | ----------------- --------------------- |
+ // | | normal text 1 | | 'More info' link | |
+ // | ----------------- --------------------- |
+ // --------------------------------------------------------------
+ //
+ // With the same parts as for the enabled echo.
+ void InitializeForDisabledEcho();
+
+ // Creates layout with text pieces initialized in
+ // |InitializeFor{Disabled|Enabled}Echo|.
+ void SetupLayout();
+
+ private:
+ enum TextPieceType {
+ TEXT_PIECE_INVALID,
+ TEXT_PIECE_LABEL,
+ TEXT_PIECE_SERVICE_NAME_LABEL,
+ TEXT_PIECE_LINK
+ };
+
+ // Information about a text piece that should be shown in the dialog.
+ struct TextPieceInfo {
+ TextPieceInfo() : type(TEXT_PIECE_INVALID) {}
+ TextPieceInfo(const string16& label,
+ TextPieceType type)
+ : label(label),
+ type(type) {
+ }
+
+ string16 label;
+ TextPieceType type;
+ };
+
+ // Adds text piece described with |info| to the |current_row|.
+ // If the whole text piece doesn't fit in the row, the row is filled with as
+ // much of words from the text piece as possible. New row are created and
+ // filled with text pieces content until the whole text piece is added to the
+ // layout.
+ // Upon completion |current_row| will be set to the last added row.
+ void SetupTextPieceLayout(const TextPieceInfo& info,
+ EchoDialogContentRowView** current_row);
+ // Creates a label view for text piece of type |type| with content |text|.
+ // |at_row_start| is set if the text_piece would be the first text piece in
+ // the row. Links are added additional padding if they are not at the row
+ // start.
+ views::Label* CreateTextPieceView(TextPieceType type,
+ const string16& label,
+ bool at_row_start);
+
+ string16 service_origin_;
+ // Listener invoked when a label of type link is clicked.
+ views::LinkListener* link_listener_;
+ // Dialog content divided into pieces with different display stype.
+ std::vector<TextPieceInfo> text_pieces_;
+
+ DISALLOW_COPY_AND_ASSIGN(EchoDialogContentView);
+};
+
+EchoDialogContentView::EchoDialogContentView(views::LinkListener* link_listener)
+ : link_listener_(link_listener) {
+ SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical, 0, 0 ,0));
+}
+
+void EchoDialogContentView::InitializeForEnabledEcho(
+ const string16& service_name,
+ const string16& origin) {
+ service_origin_ = origin;
+
+ size_t service_name_offset = 0;
+ string16 text = l10n_util::GetStringFUTF16(IDS_ECHO_CONSENT_DIALOG_TEXT,
+ service_name,
+ &service_name_offset);
+
+ text_pieces_.push_back(
+ TextPieceInfo(text.substr(0, service_name_offset), TEXT_PIECE_LABEL));
+ text_pieces_.push_back(
+ TextPieceInfo(service_name, TEXT_PIECE_SERVICE_NAME_LABEL));
+ text_pieces_.push_back(
+ TextPieceInfo(text.substr(service_name_offset + service_name.length()),
+ TEXT_PIECE_LABEL));
+ text_pieces_.push_back(TextPieceInfo(
+ l10n_util::GetStringUTF16(IDS_OFFERS_CONSENT_INFOBAR_LABEL_LEARN_MORE),
+ TEXT_PIECE_LINK));
+}
+
+void EchoDialogContentView::InitializeForDisabledEcho() {
+ text_pieces_.push_back(TextPieceInfo(
+ l10n_util::GetStringUTF16(IDS_ECHO_DISABLED_CONSENT_DIALOG_TEXT),
+ TEXT_PIECE_LABEL));
+ text_pieces_.push_back(TextPieceInfo(
+ l10n_util::GetStringUTF16(IDS_OFFERS_CONSENT_INFOBAR_LABEL_LEARN_MORE),
+ TEXT_PIECE_LINK));
+}
+
+void EchoDialogContentView::SetupLayout() {
+ EchoDialogContentRowView* current_row = new EchoDialogContentRowView();
+ AddChildView(current_row);
+ for (size_t i= 0; i < text_pieces_.size(); ++i)
+ SetupTextPieceLayout(text_pieces_[i], &current_row);
+
+ set_border(views::Border::CreateEmptyBorder(kDialogContentTopInset,
+ kDialogContentLeftInset,
+ kDialogContentBottomInset,
+ kDialogContentRightInset));
+}
+
+void EchoDialogContentView::SetupTextPieceLayout(
+ const TextPieceInfo& info,
+ EchoDialogContentRowView** current_row) {
+ if (info.label.empty())
+ return;
+
+ gfx::Size current_size = (*current_row)->GetPreferredSize();
+
+ scoped_ptr<views::Label> text_piece(
+ CreateTextPieceView(info.type, info.label, current_size.width() == 0));
+ gfx::Size text_piece_size = text_piece->GetPreferredSize();
+
+ // If the while label can fit in the free space in the current row, just add
+ // it and return.
+ if (text_piece_size.width() + current_size.width() < kDialogContentWidth) {
+ (*current_row)->AddChildView(text_piece.release());
+ return;
+ }
+
+ string16 residue = info.label;
+ gfx::Font text_piece_font = text_piece->font();
+ std::vector<string16> lines;
+
+ // Fill up the free space in the current row. |IGNORE_LONG_WORDS| is used to
+ // ensure words don't get broken in pieces. This step can be skipped if the
+ // current row is empty.
+ if (current_size.width() > 0) {
+ ui::ElideRectangleText(info.label, text_piece_font,
+ kDialogContentWidth - current_size.width(), text_piece_size.height(),
+ ui::IGNORE_LONG_WORDS, &lines);
+ if (!lines[0].empty()) {
+ text_piece->SetText(lines[0]);
+ (*current_row)->AddChildView(text_piece.release());
+
+ // Compute the part of the text piece that still has to be added to the
+ // view layout.
+ residue = info.label.substr(lines[0].length());
+ TrimWhitespace(residue, TRIM_LEADING, &residue);
+ }
+ }
+
+ // Brake up the rest of the text piece into lines shorter than
+ // |kEchoPromtWidth|, so they can fit in a single row. Use INT_MAX so the
+ // number of lines is not limited.
+ ui::ElideRectangleText(residue, text_piece_font, kDialogContentWidth, INT_MAX,
+ ui::WRAP_LONG_WORDS, &lines);
+
+ // Add lines one by one to the layout.
+ for (size_t i = 0; i < lines.size(); ++i) {
+ if ((*current_row)->GetPreferredSize().width() > 0) {
+ *current_row = new EchoDialogContentRowView();
+ AddChildView(*current_row);
+ }
+ (*current_row)->AddChildView(CreateTextPieceView(info.type, lines[i],
+ true));
+ }
+}
+
+views::Label* EchoDialogContentView::CreateTextPieceView(TextPieceType type,
+ const string16& text,
+ bool at_row_start) {
+ switch (type) {
+ case TEXT_PIECE_LABEL:
+ {
+ views::Label* label = new views::Label(text);
+ label->SetMultiLine(false);
+ label->SetFont(GetDefaultFontForEcho());
+ return label;
+ }
+ case TEXT_PIECE_SERVICE_NAME_LABEL:
+ return new EchoServiceNameLabel(text, service_origin_);
+ case TEXT_PIECE_LINK:
+ {
+ views::Link* link = new views::Link(text);
+ link->set_listener(link_listener_);
+ link->SetUnderline(false);
+ link->SetFont(GetDefaultFontForEcho());
+ if (!at_row_start) {
+ link->set_border(
+ views::Border::CreateEmptyBorder(0, kLinkLeftInset, 0, 0));
+ }
+ return link;
+ }
+ default:
+ NOTREACHED();
+ return NULL;
+ }
+}
+
+} // namespace
+
+EchoDialogView::EchoDialogView(EchoDialogListener* listener)
+ : listener_(listener),
+ ok_button_label_id_(0),
+ cancel_button_label_id_(0) {
+ SetLayoutManager(
+ new views::BoxLayout(views::BoxLayout::kVertical, 0, 0 ,0));
+}
+
+EchoDialogView::~EchoDialogView() {}
+
+void EchoDialogView::InitForEnabledEcho(const string16& service_name,
+ const string16& origin) {
+ ok_button_label_id_ = IDS_OFFERS_CONSENT_INFOBAR_ENABLE_BUTTON;
+ cancel_button_label_id_ = IDS_OFFERS_CONSENT_INFOBAR_DISABLE_BUTTON;
+
+ EchoDialogContentView* dialog_content = new EchoDialogContentView(this);
+ dialog_content->InitializeForEnabledEcho(service_name, origin);
+ dialog_content->SetupLayout();
+
+ AddChildView(dialog_content);
+}
+
+void EchoDialogView::InitForDisabledEcho() {
+ ok_button_label_id_ = 0;
+ cancel_button_label_id_ = IDS_ECHO_CONSENT_DISMISS_BUTTON;
+
+ EchoDialogContentView* dialog_content = new EchoDialogContentView(this);
+ dialog_content->InitializeForDisabledEcho();
+ dialog_content->SetupLayout();
+
+ AddChildView(dialog_content);
+}
+
+void EchoDialogView::Show(gfx::NativeWindow parent) {
+ DCHECK(cancel_button_label_id_);
+
+ views::DialogDelegateView::CreateDialogWidget(this, parent, parent);
+ set_border(views::Border::CreateEmptyBorder(0, 0, 10, 0));
+ GetWidget()->Show();
+}
+
+int EchoDialogView::GetDefaultDialogButton() const {
+ return ui::DIALOG_BUTTON_NONE;
+}
+
+int EchoDialogView::GetDialogButtons() const {
+ int buttons = ui::DIALOG_BUTTON_NONE;
+ if (ok_button_label_id_)
+ buttons |= ui::DIALOG_BUTTON_OK;
+ if (cancel_button_label_id_)
+ buttons |= ui::DIALOG_BUTTON_CANCEL;
+ return buttons;
+}
+
+bool EchoDialogView::Accept() {
+ if (listener_) {
+ listener_->OnAccept();
+ listener_ = NULL;
+ }
+ return true;
+}
+
+bool EchoDialogView::Cancel() {
+ if (listener_) {
+ listener_->OnCancel();
+ listener_ = NULL;
+ }
+ return true;
+}
+
+string16 EchoDialogView::GetDialogButtonLabel(ui::DialogButton button) const {
+ if (button == ui::DIALOG_BUTTON_OK && ok_button_label_id_)
+ return l10n_util::GetStringUTF16(ok_button_label_id_);
+ if (button == ui::DIALOG_BUTTON_CANCEL && cancel_button_label_id_)
+ return l10n_util::GetStringUTF16(cancel_button_label_id_);
+ return string16();
+}
+
+ui::ModalType EchoDialogView::GetModalType() const {
+ return ui::MODAL_TYPE_WINDOW;
+}
+
+bool EchoDialogView::ShouldShowWindowTitle() const {
+ return false;
+}
+
+bool EchoDialogView::ShouldShowWindowIcon() const {
+ return false;
+}
+
+void EchoDialogView::LinkClicked(views::Link* source, int event_flags) {
+ if (!listener_)
+ return;
+ listener_->OnMoreInfoLinkClicked();
+}
+
+EchoDialog* EchoDialog::Create(EchoDialogListener* listener) {
+ return new EchoDialogView(listener);
+}

Powered by Google App Engine
This is Rietveld 408576698