Chromium Code Reviews| Index: chrome/browser/ui/views/proximity_auth/proximity_auth_error_bubble_view.cc |
| diff --git a/chrome/browser/ui/views/proximity_auth/proximity_auth_error_bubble_view.cc b/chrome/browser/ui/views/proximity_auth/proximity_auth_error_bubble_view.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..0f80790a3c4c7e22055603fd5633473843c3391c |
| --- /dev/null |
| +++ b/chrome/browser/ui/views/proximity_auth/proximity_auth_error_bubble_view.cc |
| @@ -0,0 +1,119 @@ |
| +// Copyright 2014 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/proximity_auth/proximity_auth_error_bubble_view.h" |
| + |
| +#include "base/strings/string_util.h" |
| +#include "chrome/browser/ui/proximity_auth/proximity_auth_error_bubble.h" |
| +#include "content/public/browser/page_navigator.h" |
| +#include "content/public/browser/web_contents.h" |
| +#include "grit/theme_resources.h" |
| +#include "ui/base/resource/resource_bundle.h" |
| +#include "ui/gfx/geometry/rect.h" |
| +#include "ui/gfx/range/range.h" |
| +#include "ui/views/bubble/bubble_border.h" |
| +#include "ui/views/controls/image_view.h" |
| +#include "ui/views/controls/styled_label.h" |
| +#include "ui/views/layout/grid_layout.h" |
| +#include "ui/views/widget/widget.h" |
| + |
| +namespace { |
| + |
| +// The bubble's content area width, in device pixels. |
|
Tim Song
2015/01/15 19:29:24
nit: device independent pixels
Ilya Sherman
2015/01/16 05:39:42
Done.
|
| +const int kBubbleWidth = 296; |
| + |
| +// The padding between columns in the bubble. |
| +const int kBubbleIntraColumnPadding = 6; |
| + |
| +// A styled label that maintains a fixed preferred size. |
| +class FixedSizeStyledLabel : public views::StyledLabel { |
| + public: |
| + FixedSizeStyledLabel(const base::string16& text, |
| + views::StyledLabelListener* listener) |
| + : views::StyledLabel(text, listener) {} |
| + ~FixedSizeStyledLabel() override {} |
| + |
| + private: |
| + gfx::Size GetPreferredSize() const override { |
| + return size(); |
| + } |
| + |
| + DISALLOW_COPY_AND_ASSIGN(FixedSizeStyledLabel); |
| +}; |
| + |
| +} // namespace |
| + |
| +// static |
| +void ProximityAuthErrorBubble::ShowErrorBubble( |
| + const base::string16& message, |
| + const gfx::Range& link_range, |
| + const GURL& link_url, |
| + const gfx::Rect& anchor_rect, |
| + content::WebContents* web_contents) { |
| + // The created bubble is owned by the views hierarchy. |
| + new ProximityAuthErrorBubbleView( |
| + message, link_range, link_url, anchor_rect, web_contents); |
| +} |
| + |
| +ProximityAuthErrorBubbleView::ProximityAuthErrorBubbleView( |
| + const base::string16& message, |
| + const gfx::Range& link_range, |
| + const GURL& link_url, |
| + const gfx::Rect& anchor_rect, |
| + content::WebContents* web_contents) |
| + : WebContentsObserver(web_contents), |
| + link_url_(link_url) { |
| + SetAnchorRect(anchor_rect); |
| + set_arrow(views::BubbleBorder::LEFT_TOP); |
| + |
| + // Define this grid layout for the bubble: |
| + // ---------------------------- |
| + // | icon | padding | message | |
| + // ---------------------------- |
| + scoped_ptr<views::GridLayout> layout(new views::GridLayout(this)); |
| + views::ColumnSet* columns = layout->AddColumnSet(0); |
| + columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::LEADING, 0, |
| + views::GridLayout::USE_PREF, 0, 0); |
| + columns->AddPaddingColumn(0, kBubbleIntraColumnPadding); |
| + columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::LEADING, 0, |
|
Tim Song
2015/01/15 19:29:24
Can't you use views::GridLayout::FIXED for the sec
Ilya Sherman
2015/01/16 05:39:42
Done.
|
| + views::GridLayout::USE_PREF, 0, 0); |
| + |
| + // Construct the views. |
| + scoped_ptr<views::ImageView> warning_icon(new views::ImageView()); |
| + ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); |
| + warning_icon->SetImage(*bundle.GetImageSkiaNamed(IDR_WARNING)); |
| + |
| + scoped_ptr<FixedSizeStyledLabel> label( |
| + new FixedSizeStyledLabel(message, this)); |
| + if (!link_range.is_empty()) { |
| + label->AddStyleRange(link_range, |
| + views::StyledLabel::RangeStyleInfo::CreateForLink()); |
| + } |
| + label->SizeToFit( |
| + kBubbleWidth - margins().width() - warning_icon->size().width() - |
| + kBubbleIntraColumnPadding); |
| + |
| + // Add the views to the bubble. |
| + layout->StartRow(0, 0); |
| + layout->AddView(warning_icon.release()); |
| + layout->AddView(label.release()); |
| + SetLayoutManager(layout.release()); |
| + |
| + views::Widget* widget = views::BubbleDelegateView::CreateBubble(this); |
| + widget->Show(); |
| +} |
| + |
| +ProximityAuthErrorBubbleView::~ProximityAuthErrorBubbleView() { |
| +} |
| + |
| +void ProximityAuthErrorBubbleView::StyledLabelLinkClicked( |
| + const gfx::Range& range, |
| + int event_flags) { |
| + if (!web_contents()) |
| + return; |
| + |
| + web_contents()->OpenURL(content::OpenURLParams( |
| + link_url_, content::Referrer(), NEW_FOREGROUND_TAB, |
| + ui::PAGE_TRANSITION_LINK, false)); |
| +} |