summaryrefslogtreecommitdiffstats
path: root/chromium/ui/message_center/views
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/ui/message_center/views')
-rw-r--r--chromium/ui/message_center/views/bounded_label.cc73
-rw-r--r--chromium/ui/message_center/views/bounded_label.h20
-rw-r--r--chromium/ui/message_center/views/bounded_label_unittest.cc18
-rw-r--r--chromium/ui/message_center/views/constants.h3
-rw-r--r--chromium/ui/message_center/views/group_view.cc280
-rw-r--r--chromium/ui/message_center/views/group_view.h77
-rw-r--r--chromium/ui/message_center/views/message_bubble_base.cc1
-rw-r--r--chromium/ui/message_center/views/message_center_bubble.cc15
-rw-r--r--chromium/ui/message_center/views/message_center_bubble.h2
-rw-r--r--chromium/ui/message_center/views/message_center_button_bar.cc51
-rw-r--r--chromium/ui/message_center/views/message_center_button_bar.h12
-rw-r--r--chromium/ui/message_center/views/message_center_controller.h15
-rw-r--r--chromium/ui/message_center/views/message_center_view.cc387
-rw-r--r--chromium/ui/message_center/views/message_center_view.h38
-rw-r--r--chromium/ui/message_center/views/message_center_view_unittest.cc67
-rw-r--r--chromium/ui/message_center/views/message_popup_collection.cc142
-rw-r--r--chromium/ui/message_center/views/message_popup_collection.h24
-rw-r--r--chromium/ui/message_center/views/message_popup_collection_unittest.cc10
-rw-r--r--chromium/ui/message_center/views/message_view.cc209
-rw-r--r--chromium/ui/message_center/views/message_view.h35
-rw-r--r--chromium/ui/message_center/views/message_view_context_menu_controller.cc45
-rw-r--r--chromium/ui/message_center/views/message_view_context_menu_controller.h34
-rw-r--r--chromium/ui/message_center/views/notification_button.cc20
-rw-r--r--chromium/ui/message_center/views/notification_button.h8
-rw-r--r--chromium/ui/message_center/views/notification_view.cc614
-rw-r--r--chromium/ui/message_center/views/notification_view.h49
-rw-r--r--chromium/ui/message_center/views/notification_view_unittest.cc323
-rw-r--r--chromium/ui/message_center/views/notifier_settings_view.cc66
-rw-r--r--chromium/ui/message_center/views/notifier_settings_view.h8
-rw-r--r--chromium/ui/message_center/views/padded_button.cc4
-rw-r--r--chromium/ui/message_center/views/padded_button.h4
-rw-r--r--chromium/ui/message_center/views/proportional_image_view.cc73
-rw-r--r--chromium/ui/message_center/views/proportional_image_view.h9
-rw-r--r--chromium/ui/message_center/views/toast_contents_view.cc96
-rw-r--r--chromium/ui/message_center/views/toast_contents_view.h21
35 files changed, 1369 insertions, 1484 deletions
diff --git a/chromium/ui/message_center/views/bounded_label.cc b/chromium/ui/message_center/views/bounded_label.cc
index 2b8423b6865..99c66f80b77 100644
--- a/chromium/ui/message_center/views/bounded_label.cc
+++ b/chromium/ui/message_center/views/bounded_label.cc
@@ -10,6 +10,7 @@
#include "base/strings/utf_string_conversions.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/text_elider.h"
+#include "ui/gfx/text_utils.h"
#include "ui/views/controls/label.h"
namespace {
@@ -24,7 +25,7 @@ namespace message_center {
// InnerBoundedLabel is a views::Label subclass that does all of the work for
// BoundedLabel. It is kept private to prevent outside code from calling a
-// number of views::Label methods like setFont() that break BoundedLabel's
+// number of views::Label methods like SetFontList() that break BoundedLabel's
// caching but can't be overridden.
//
// TODO(dharcourt): Move the line limiting functionality to views::Label to make
@@ -40,7 +41,10 @@ class InnerBoundedLabel : public views::Label {
// Pass in a -1 width to use the preferred width, a -1 limit to skip limits.
int GetLinesForWidthAndLimit(int width, int limit);
gfx::Size GetSizeForWidthAndLines(int width, int lines);
- std::vector<string16> GetWrappedText(int width, int lines);
+ std::vector<base::string16> GetWrappedText(int width, int lines);
+
+ // Overridden from views::Label.
+ virtual void SetText(const base::string16& text) OVERRIDE;
protected:
// Overridden from views::Label.
@@ -57,7 +61,7 @@ class InnerBoundedLabel : public views::Label {
void SetCachedSize(std::pair<int, int> width_and_lines, gfx::Size size);
const BoundedLabel* owner_; // Weak reference.
- string16 wrapped_text_;
+ base::string16 wrapped_text_;
int wrapped_text_width_;
int wrapped_text_lines_;
std::map<int, int> lines_cache_;
@@ -108,8 +112,8 @@ gfx::Size InnerBoundedLabel::GetSizeForWidthAndLines(int width, int lines) {
int text_width = (width < 0) ? std::numeric_limits<int>::max() :
std::max(width - insets.width(), 0);
int text_height = std::numeric_limits<int>::max();
- std::vector<string16> wrapped = GetWrappedText(text_width, lines);
- gfx::Canvas::SizeStringInt(JoinString(wrapped, '\n'), font(),
+ std::vector<base::string16> wrapped = GetWrappedText(text_width, lines);
+ gfx::Canvas::SizeStringInt(JoinString(wrapped, '\n'), font_list(),
&text_width, &text_height,
owner_->GetLineHeight(),
GetTextFlags());
@@ -120,28 +124,25 @@ gfx::Size InnerBoundedLabel::GetSizeForWidthAndLines(int width, int lines) {
return size;
}
-std::vector<string16> InnerBoundedLabel::GetWrappedText(int width, int lines) {
+std::vector<base::string16> InnerBoundedLabel::GetWrappedText(int width,
+ int lines) {
// Short circuit simple case.
if (width == 0 || lines == 0)
- return std::vector<string16>();
+ return std::vector<base::string16>();
// Restrict line limit to ensure (lines + 1) * line_height <= INT_MAX and
// use it to calculate a reasonable text height.
int height = std::numeric_limits<int>::max();
if (lines > 0) {
- int line_height = std::max(font().GetHeight(), 2); // At least 2 pixels.
+ int line_height = std::max(font_list().GetHeight(),
+ 2); // At least 2 pixels.
int max_lines = std::numeric_limits<int>::max() / line_height - 1;
lines = std::min(lines, max_lines);
height = (lines + 1) * line_height;
}
- // Try to ensure that the width is no smaller than the width of the text's
- // characters to avoid the http://crbug.com/237700 infinite loop.
- // TODO(dharcourt): Remove when http://crbug.com/237700 is fixed.
- width = std::max(width, 2 * font().GetStringWidth(UTF8ToUTF16("W")));
-
// Wrap, using INT_MAX for -1 widths that indicate no wrapping.
- std::vector<string16> wrapped;
+ std::vector<base::string16> wrapped;
gfx::ElideRectangleText(text(), font_list(),
(width < 0) ? std::numeric_limits<int>::max() : width,
height, gfx::WRAP_LONG_WORDS, &wrapped);
@@ -151,9 +152,10 @@ std::vector<string16> InnerBoundedLabel::GetWrappedText(int width, int lines) {
// Add an ellipsis to the last line. If this ellipsis makes the last line
// too wide, that line will be further elided by the gfx::ElideText below,
// so for example "ABC" could become "ABC..." and then "AB...".
- string16 last = wrapped[lines - 1] + UTF8ToUTF16(gfx::kEllipsis);
- if (width > 0 && font().GetStringWidth(last) > width)
- last = gfx::ElideText(last, font(), width, gfx::ELIDE_AT_END);
+ base::string16 last =
+ wrapped[lines - 1] + base::UTF8ToUTF16(gfx::kEllipsis);
+ if (width > 0 && gfx::GetStringWidth(last, font_list()) > width)
+ last = gfx::ElideText(last, font_list(), width, gfx::ELIDE_TAIL);
wrapped.resize(lines - 1);
wrapped.push_back(last);
}
@@ -184,6 +186,11 @@ void InnerBoundedLabel::OnPaint(gfx::Canvas* canvas) {
}
}
+void InnerBoundedLabel::SetText(const base::string16& text) {
+ views::Label::SetText(text);
+ ClearCaches();
+}
+
int InnerBoundedLabel::GetTextFlags() {
int flags = gfx::Canvas::MULTI_LINE | gfx::Canvas::CHARACTER_BREAK;
@@ -191,8 +198,11 @@ int InnerBoundedLabel::GetTextFlags() {
if (SkColorGetA(background_color()) != 0xFF)
flags |= gfx::Canvas::NO_SUBPIXEL_RENDERING;
- if (directionality_mode() ==
- views::Label::AUTO_DETECT_DIRECTIONALITY) {
+ if (directionality_mode() == gfx::DIRECTIONALITY_FORCE_LTR) {
+ flags |= gfx::Canvas::FORCE_LTR_DIRECTIONALITY;
+ } else if (directionality_mode() == gfx::DIRECTIONALITY_FORCE_RTL) {
+ flags |= gfx::Canvas::FORCE_RTL_DIRECTIONALITY;
+ } else if (directionality_mode() == gfx::DIRECTIONALITY_FROM_TEXT) {
base::i18n::TextDirection direction =
base::i18n::GetFirstStrongCharacterDirection(text());
if (direction == base::i18n::RIGHT_TO_LEFT)
@@ -257,14 +267,15 @@ void InnerBoundedLabel::SetCachedSize(std::pair<int, int> width_and_lines,
// BoundedLabel ///////////////////////////////////////////////////////////
-BoundedLabel::BoundedLabel(const string16& text, const gfx::FontList& font_list)
+BoundedLabel::BoundedLabel(const base::string16& text,
+ const gfx::FontList& font_list)
: line_limit_(-1) {
label_.reset(new InnerBoundedLabel(*this));
label_->SetFontList(font_list);
label_->SetText(text);
}
-BoundedLabel::BoundedLabel(const string16& text)
+BoundedLabel::BoundedLabel(const base::string16& text)
: line_limit_(-1) {
label_.reset(new InnerBoundedLabel(*this));
label_->SetText(text);
@@ -286,6 +297,10 @@ void BoundedLabel::SetLineLimit(int lines) {
line_limit_ = std::max(lines, -1);
}
+void BoundedLabel::SetText(const base::string16& text) {
+ label_->SetText(text);
+}
+
int BoundedLabel::GetLineHeight() const {
return label_->line_height();
}
@@ -307,25 +322,25 @@ int BoundedLabel::GetBaseline() const {
return label_->GetBaseline();
}
-gfx::Size BoundedLabel::GetPreferredSize() {
+gfx::Size BoundedLabel::GetPreferredSize() const {
return visible() ? label_->GetSizeForWidthAndLines(-1, -1) : gfx::Size();
}
-int BoundedLabel::GetHeightForWidth(int width) {
+int BoundedLabel::GetHeightForWidth(int width) const {
return visible() ?
label_->GetSizeForWidthAndLines(width, line_limit_).height() : 0;
}
-void BoundedLabel::Paint(gfx::Canvas* canvas) {
+void BoundedLabel::Paint(gfx::Canvas* canvas, const views::CullSet& cull_set) {
if (visible())
- label_->Paint(canvas);
+ label_->Paint(canvas, cull_set);
}
-bool BoundedLabel::HitTestRect(const gfx::Rect& rect) const {
- return label_->HitTestRect(rect);
+bool BoundedLabel::CanProcessEventsWithinSubtree() const {
+ return label_->CanProcessEventsWithinSubtree();
}
-void BoundedLabel::GetAccessibleState(ui::AccessibleViewState* state) {
+void BoundedLabel::GetAccessibleState(ui::AXViewState* state) {
label_->GetAccessibleState(state);
}
@@ -338,7 +353,7 @@ void BoundedLabel::OnNativeThemeChanged(const ui::NativeTheme* theme) {
label_->SetNativeTheme(theme);
}
-string16 BoundedLabel::GetWrappedTextForTest(int width, int lines) {
+base::string16 BoundedLabel::GetWrappedTextForTest(int width, int lines) {
return JoinString(label_->GetWrappedText(width, lines), '\n');
}
diff --git a/chromium/ui/message_center/views/bounded_label.h b/chromium/ui/message_center/views/bounded_label.h
index d6b2f49a519..9a9e6d4bc4c 100644
--- a/chromium/ui/message_center/views/bounded_label.h
+++ b/chromium/ui/message_center/views/bounded_label.h
@@ -33,13 +33,14 @@ class BoundedLabelTest;
// bounded_label.cc file for details.
class MESSAGE_CENTER_EXPORT BoundedLabel : public views::View {
public:
- BoundedLabel(const string16& text, const gfx::FontList& font_list);
- BoundedLabel(const string16& text);
+ BoundedLabel(const base::string16& text, const gfx::FontList& font_list);
+ BoundedLabel(const base::string16& text);
virtual ~BoundedLabel();
void SetColors(SkColor textColor, SkColor backgroundColor);
void SetLineHeight(int height); // Pass in 0 for default height.
void SetLineLimit(int lines); // Pass in -1 for no limit.
+ void SetText(const base::string16& text); // Additionally clears caches.
int GetLineHeight() const;
int GetLineLimit() const;
@@ -48,13 +49,14 @@ class MESSAGE_CENTER_EXPORT BoundedLabel : public views::View {
int GetLinesForWidthAndLimit(int width, int limit);
gfx::Size GetSizeForWidthAndLines(int width, int lines);
- // Overridden from views::View.
+ // views::View:
virtual int GetBaseline() const OVERRIDE;
- virtual gfx::Size GetPreferredSize() OVERRIDE;
- virtual int GetHeightForWidth(int width) OVERRIDE;
- virtual void Paint(gfx::Canvas* canvas) OVERRIDE;
- virtual bool HitTestRect(const gfx::Rect& rect) const OVERRIDE;
- virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE;
+ virtual gfx::Size GetPreferredSize() const OVERRIDE;
+ virtual int GetHeightForWidth(int width) const OVERRIDE;
+ virtual void Paint(gfx::Canvas* canvas,
+ const views::CullSet& cull_set) OVERRIDE;
+ virtual bool CanProcessEventsWithinSubtree() const OVERRIDE;
+ virtual void GetAccessibleState(ui::AXViewState* state) OVERRIDE;
protected:
// Overridden from views::View.
@@ -64,7 +66,7 @@ class MESSAGE_CENTER_EXPORT BoundedLabel : public views::View {
private:
friend class test::BoundedLabelTest;
- string16 GetWrappedTextForTest(int width, int lines);
+ base::string16 GetWrappedTextForTest(int width, int lines);
scoped_ptr<InnerBoundedLabel> label_;
int line_limit_;
diff --git a/chromium/ui/message_center/views/bounded_label_unittest.cc b/chromium/ui/message_center/views/bounded_label_unittest.cc
index bdfb0aceeb6..90452e2e1e3 100644
--- a/chromium/ui/message_center/views/bounded_label_unittest.cc
+++ b/chromium/ui/message_center/views/bounded_label_unittest.cc
@@ -23,9 +23,9 @@ namespace test {
class BoundedLabelTest : public testing::Test {
public:
BoundedLabelTest() {
- digit_pixels_ = gfx::GetStringWidth(UTF8ToUTF16("0"), font_list_);
- space_pixels_ = gfx::GetStringWidth(UTF8ToUTF16(" "), font_list_);
- ellipsis_pixels_ = gfx::GetStringWidth(UTF8ToUTF16("\xE2\x80\xA6"),
+ digit_pixels_ = gfx::GetStringWidth(base::UTF8ToUTF16("0"), font_list_);
+ space_pixels_ = gfx::GetStringWidth(base::UTF8ToUTF16(" "), font_list_);
+ ellipsis_pixels_ = gfx::GetStringWidth(base::UTF8ToUTF16("\xE2\x80\xA6"),
font_list_);
}
@@ -35,10 +35,10 @@ class BoundedLabelTest : public testing::Test {
// with an ellipses character (UTF8 "\xE2\x80\xA6") and returns a string16
// with the results. This allows test strings to be specified as ASCII const
// char* strings, making tests more readable and easier to write.
- string16 ToString(const char* string) {
- const string16 periods = UTF8ToUTF16("...");
- const string16 ellipses = UTF8ToUTF16("\xE2\x80\xA6");
- string16 result = UTF8ToUTF16(string);
+ base::string16 ToString(const char* string) {
+ const base::string16 periods = base::UTF8ToUTF16("...");
+ const base::string16 ellipses = base::UTF8ToUTF16("\xE2\x80\xA6");
+ base::string16 result = base::UTF8ToUTF16(string);
ReplaceSubstringsAfterOffset(&result, 0, periods, ellipses);
return result;
}
@@ -58,7 +58,7 @@ class BoundedLabelTest : public testing::Test {
}
// Exercise BounderLabel::GetWrappedText() using the fixture's test label.
- string16 GetWrappedText(int width) {
+ base::string16 GetWrappedText(int width) {
return label_->GetWrappedTextForTest(width, lines_);
}
@@ -71,7 +71,7 @@ class BoundedLabelTest : public testing::Test {
protected:
// Creates a label to test with. Returns this fixture, which can be used to
// test the newly created label using the exercise methods above.
- BoundedLabelTest& Label(string16 text, int lines) {
+ BoundedLabelTest& Label(base::string16 text, int lines) {
lines_ = lines;
label_.reset(new BoundedLabel(text, font_list_));
label_->SetLineLimit(lines_);
diff --git a/chromium/ui/message_center/views/constants.h b/chromium/ui/message_center/views/constants.h
index d03ec7f0b79..f2995dd45b5 100644
--- a/chromium/ui/message_center/views/constants.h
+++ b/chromium/ui/message_center/views/constants.h
@@ -31,8 +31,7 @@ const int kButtonTitleTopPadding = 0;
// Character limits: Displayed text will be subject to the line limits above,
// but we also remove trailing characters from text to reduce processing cost.
// Character limit = pixels per line * line limit / min. pixels per character.
-const size_t kTitleCharacterLimit =
- message_center::kNotificationWidth * message_center::kTitleLineLimit / 4;
+const int kMinPixelsPerTitleCharacter = 4;
const size_t kMessageCharacterLimit =
message_center::kNotificationWidth *
message_center::kMessageExpandedLineLimit / 3;
diff --git a/chromium/ui/message_center/views/group_view.cc b/chromium/ui/message_center/views/group_view.cc
deleted file mode 100644
index 384c2d2e7b4..00000000000
--- a/chromium/ui/message_center/views/group_view.cc
+++ /dev/null
@@ -1,280 +0,0 @@
-// 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 "ui/message_center/views/group_view.h"
-
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_util.h"
-#include "base/strings/utf_string_conversions.h"
-#include "grit/ui_resources.h"
-#include "grit/ui_strings.h"
-#include "ui/base/l10n/l10n_util.h"
-#include "ui/base/layout.h"
-#include "ui/base/resource/resource_bundle.h"
-#include "ui/gfx/canvas.h"
-#include "ui/gfx/size.h"
-#include "ui/gfx/skia_util.h"
-#include "ui/gfx/text_elider.h"
-#include "ui/message_center/message_center.h"
-#include "ui/message_center/message_center_style.h"
-#include "ui/message_center/message_center_tray.h"
-#include "ui/message_center/message_center_util.h"
-#include "ui/message_center/notification.h"
-#include "ui/message_center/views/bounded_label.h"
-#include "ui/message_center/views/constants.h"
-#include "ui/message_center/views/notification_button.h"
-#include "ui/message_center/views/proportional_image_view.h"
-#include "ui/native_theme/native_theme.h"
-#include "ui/views/background.h"
-#include "ui/views/border.h"
-#include "ui/views/controls/button/image_button.h"
-#include "ui/views/controls/image_view.h"
-#include "ui/views/controls/label.h"
-#include "ui/views/layout/box_layout.h"
-#include "ui/views/layout/fill_layout.h"
-#include "ui/views/widget/widget.h"
-
-#if defined(USE_AURA)
-#include "ui/base/cursor/cursor.h"
-#endif
-
-namespace {
-
-// static
-views::Border* MakeTextBorder(int padding, int top, int bottom) {
- // Split the padding between the top and the bottom, then add the extra space.
- return views::Border::CreateEmptyBorder(padding / 2 + top,
- message_center::kTextLeftPadding,
- (padding + 1) / 2 + bottom,
- message_center::kTextRightPadding);
-}
-
-} // namespace
-
-namespace message_center {
-
-// GroupView ////////////////////////////////////////////////////////////
-
-GroupView::GroupView(MessageCenterController* controller,
- const NotifierId& notifier_id,
- const Notification& last_notification,
- const gfx::ImageSkia& group_icon,
- int group_size)
- : MessageView(this,
- last_notification.id(),
- notifier_id,
- last_notification.display_source()),
- controller_(controller),
- notifier_id_(notifier_id),
- display_source_(last_notification.display_source()),
- group_icon_(group_icon),
- group_size_(group_size),
- last_notification_id_(last_notification.id()),
- background_view_(NULL),
- top_view_(NULL),
- bottom_view_(NULL),
- title_view_(NULL),
- message_view_(NULL),
- context_message_view_(NULL),
- icon_view_(NULL)
-{
- std::vector<string16> accessible_lines;
- // TODO (dimich): move to MessageView
- // Create the opaque background that's above the view's shadow.
- background_view_ = new views::View();
- background_view_->set_background(
- views::Background::CreateSolidBackground(
- message_center::kNotificationBackgroundColor));
-
- // Create the top_view_, which collects into a vertical box all content
- // at the top of the notification (to the right of the icon) except for the
- // close button.
- top_view_ = new views::View();
- top_view_->SetLayoutManager(
- new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0));
- top_view_->set_border(views::Border::CreateEmptyBorder(
- kTextTopPadding - 8, 0, kTextBottomPadding - 5, 0));
-
- const gfx::FontList default_label_font_list = views::Label().font_list();
-
- // Create the title view if appropriate.
- const gfx::FontList& font_list =
- default_label_font_list.DeriveFontListWithSizeDelta(2);
- int padding = kTitleLineHeight - font_list.GetHeight();
-
- title_view_ = new BoundedLabel(
- gfx::TruncateString(string16(last_notification.title()),
- kTitleCharacterLimit),
- font_list);
- accessible_lines.push_back(last_notification.title());
- title_view_->SetLineHeight(kTitleLineHeight);
- title_view_->SetLineLimit(message_center::kTitleLineLimit);
- title_view_->SetColors(message_center::kRegularTextColor,
- kRegularTextBackgroundColor);
- title_view_->set_border(MakeTextBorder(padding, 3, 0));
- top_view_->AddChildView(title_view_);
-
- // Create the message view if appropriate.
- if (!last_notification.message().empty()) {
- int padding = kMessageLineHeight - default_label_font_list.GetHeight();
- message_view_ = new BoundedLabel(
- gfx::TruncateString(last_notification.message(),
- kMessageCharacterLimit));
- message_view_->SetLineHeight(kMessageLineHeight);
- message_view_->SetColors(message_center::kRegularTextColor,
- kDimTextBackgroundColor);
- message_view_->set_border(MakeTextBorder(padding, 4, 0));
- top_view_->AddChildView(message_view_);
- accessible_lines.push_back(last_notification.message());
- }
-
- // Create the context message view if appropriate.
- if (!last_notification.context_message().empty()) {
- int padding = kMessageLineHeight - default_label_font_list.GetHeight();
- context_message_view_ = new BoundedLabel(gfx::TruncateString(
- last_notification.context_message(), kContextMessageCharacterLimit),
- default_label_font_list);
- context_message_view_->SetLineLimit(
- message_center::kContextMessageLineLimit);
- context_message_view_->SetLineHeight(kMessageLineHeight);
- context_message_view_->SetColors(message_center::kDimTextColor,
- kContextTextBackgroundColor);
- context_message_view_->set_border(MakeTextBorder(padding, 4, 0));
- top_view_->AddChildView(context_message_view_);
- accessible_lines.push_back(last_notification.context_message());
- }
-
- // Create the notification icon view.
- icon_view_ =
- new ProportionalImageView(last_notification.icon().AsImageSkia());
- icon_view_->set_background(views::Background::CreateSolidBackground(
- kIconBackgroundColor));
-
- // Create the bottom_view_, which collects into a vertical box all content
- // below the notification icon except for the expandGroup button.
- bottom_view_ = new views::View();
- bottom_view_->SetLayoutManager(
- new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0));
-
- // Create "N more.." action button
- views::View* separator = new views::ImageView();
- separator->set_border(views::Border::CreateSolidSidedBorder(
- 1, 0, 0, 0, kButtonSeparatorColor));
- bottom_view_->AddChildView(separator);
- more_button_ = new NotificationButton(this);
- string16 button_title =
- l10n_util::GetStringFUTF16(IDS_MESSAGE_CENTER_MORE_FROM,
- base::IntToString16(group_size_),
- display_source_);
- more_button_->SetTitle(button_title);
- more_button_->SetIcon(group_icon_);
- bottom_view_->AddChildView(more_button_);
-
- // Put together the different content and control views. Layering those allows
- // for proper layout logic and it also allows the close button to
- // overlap the content as needed to provide large enough click and touch area.
- AddChildView(background_view_);
- AddChildView(top_view_);
- AddChildView(icon_view_);
- AddChildView(bottom_view_);
- AddChildView(close_button());
- set_accessible_name(JoinString(accessible_lines, '\n'));
-}
-
-GroupView::~GroupView() {
-}
-
-gfx::Size GroupView::GetPreferredSize() {
- int top_width = top_view_->GetPreferredSize().width();
- int bottom_width = bottom_view_->GetPreferredSize().width();
- int preferred_width = std::max(top_width, bottom_width) + GetInsets().width();
- return gfx::Size(preferred_width, GetHeightForWidth(preferred_width));
-}
-
-int GroupView::GetHeightForWidth(int width) {
- int content_width = width - GetInsets().width();
- int top_height = top_view_->GetHeightForWidth(content_width);
- int bottom_height = bottom_view_->GetHeightForWidth(content_width);
- int content_height = std::max(top_height, kIconSize) + bottom_height;
-
- // Adjust the height to make sure there is at least 16px of space below the
- // icon if there is any space there (<http://crbug.com/232966>).
- if (content_height > kIconSize)
- content_height = std::max(content_height,
- kIconSize + message_center::kIconBottomPadding);
-
- return content_height + GetInsets().height();
-}
-
-void GroupView::Layout() {
- gfx::Insets insets = GetInsets();
- int content_width = width() - insets.width();
- int content_right = width() - insets.right();
-
- // Background.
- background_view_->SetBounds(insets.left(), insets.top(),
- content_width, height() - insets.height());
-
- // Top views.
- int top_height = top_view_->GetHeightForWidth(content_width);
- top_view_->SetBounds(insets.left(), insets.top(), content_width, top_height);
-
- // Icon.
- icon_view_->SetBounds(insets.left(), insets.top(), kIconSize, kIconSize);
-
- // Bottom views.
- int bottom_y = insets.top() + std::max(top_height, kIconSize);
- int bottom_height = bottom_view_->GetHeightForWidth(content_width);
- bottom_view_->SetBounds(insets.left(), bottom_y,
- content_width, bottom_height);
-
- // Close button.
- gfx::Size close_size(close_button()->GetPreferredSize());
- close_button()->SetBounds(content_right - close_size.width(), insets.top(),
- close_size.width(), close_size.height());
-}
-
-void GroupView::OnFocus() {
- MessageView::OnFocus();
- ScrollRectToVisible(GetLocalBounds());
-}
-
-gfx::NativeCursor GroupView::GetCursor(const ui::MouseEvent& event) {
-// If we ever have non-Aura views environment, this will fail compilation.
-#if defined(USE_AURA)
- return ui::kCursorHand;
-#endif
-}
-
-void GroupView::ButtonPressed(views::Button* sender,
- const ui::Event& event) {
- if (sender == more_button_) {
- controller_->ExpandGroup(notifier_id_);
- return;
- }
- // Let the superclass handle anything other than action buttons.
- // Warning: This may cause the GroupView itself to be deleted,
- // so don't do anything afterwards.
- MessageView::ButtonPressed(sender, event);
-}
-
-void GroupView::ClickOnNotification(const std::string& notification_id) {
- controller_->GroupBodyClicked(notification_id);
-}
-
-void GroupView::RemoveNotification(const std::string& notification_id,
- bool by_user) {
- controller_->RemoveGroup(notifier_id_);
-}
-
-void GroupView::DisableNotificationsFromThisSource(
- const NotifierId& notifier_id) {
- controller_->DisableNotificationsFromThisSource(notifier_id);
-}
-
-void GroupView::ShowNotifierSettingsBubble() {
- controller_->ShowNotifierSettingsBubble();
-}
-
-} // namespace message_center
diff --git a/chromium/ui/message_center/views/group_view.h b/chromium/ui/message_center/views/group_view.h
deleted file mode 100644
index d2746a2546c..00000000000
--- a/chromium/ui/message_center/views/group_view.h
+++ /dev/null
@@ -1,77 +0,0 @@
-// 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.
-
-#ifndef UI_MESSAGE_CENTER_VIEWS_GROUP_VIEW_H_
-#define UI_MESSAGE_CENTER_VIEWS_GROUP_VIEW_H_
-
-#include "ui/gfx/image/image_skia.h"
-#include "ui/message_center/views/message_center_controller.h"
-#include "ui/message_center/views/message_center_view.h"
-#include "ui/message_center/views/message_view.h"
-
-namespace message_center {
-
-class BoundedLabel;
-class MessageCenter;
-class NotificationButton;
-
-// View that displays a placeholder representing several notifications and a
-// button to expand it into a set of individual notifications.
-class GroupView : public MessageView, public MessageViewController {
- public:
- // The group view currently shows the latest notificaiton w/o buttons
- // and a single button like "N more from XYZ".
- // Each GroupView has a notifier_id which it uses to report clicks and other
- // user actions to Client.
- GroupView(MessageCenterController* controller,
- const NotifierId& notifier_id,
- const Notification& last_notification,
- const gfx::ImageSkia& group_icon,
- int group_size);
-
- virtual ~GroupView();
-
- // Overridden from views::View:
- virtual gfx::Size GetPreferredSize() OVERRIDE;
- virtual int GetHeightForWidth(int width) OVERRIDE;
- virtual void Layout() OVERRIDE;
- virtual void OnFocus() OVERRIDE;
- virtual gfx::NativeCursor GetCursor(const ui::MouseEvent& event) OVERRIDE;
-
- // Overridden from MessageView:
- virtual void ButtonPressed(views::Button* sender,
- const ui::Event& event) OVERRIDE;
-
- // Overridden from MessageViewController:
- virtual void ClickOnNotification(const std::string& notification_id) OVERRIDE;
- virtual void RemoveNotification(const std::string& notification_id,
- bool by_user) OVERRIDE;
- virtual void DisableNotificationsFromThisSource(
- const NotifierId& notifier_id) OVERRIDE;
- virtual void ShowNotifierSettingsBubble() OVERRIDE;
-
- private:
- MessageCenterController* controller_; // Weak, controls lifetime of views.
- NotifierId notifier_id_;
- string16 display_source_;
- gfx::ImageSkia group_icon_;
- int group_size_;
- std::string last_notification_id_;
-
- // Weak references to GroupView descendants owned by their parents.
- views::View* background_view_;
- views::View* top_view_;
- views::View* bottom_view_;
- BoundedLabel* title_view_;
- BoundedLabel* message_view_;
- BoundedLabel* context_message_view_;
- views::View* icon_view_;
- NotificationButton* more_button_;
-
- DISALLOW_COPY_AND_ASSIGN(GroupView);
-};
-
-} // namespace message_center
-
-#endif // UI_MESSAGE_CENTER_VIEWS_GROUP_VIEW_H_
diff --git a/chromium/ui/message_center/views/message_bubble_base.cc b/chromium/ui/message_center/views/message_bubble_base.cc
index e517c4af24d..c230c2d04ce 100644
--- a/chromium/ui/message_center/views/message_bubble_base.cc
+++ b/chromium/ui/message_center/views/message_bubble_base.cc
@@ -6,7 +6,6 @@
#include "base/bind.h"
#include "ui/message_center/message_center_style.h"
-#include "ui/message_center/message_center_util.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_observer.h"
diff --git a/chromium/ui/message_center/views/message_center_bubble.cc b/chromium/ui/message_center/views/message_center_bubble.cc
index 5886531b2db..ed93d7fa0c8 100644
--- a/chromium/ui/message_center/views/message_center_bubble.cc
+++ b/chromium/ui/message_center/views/message_center_bubble.cc
@@ -4,8 +4,9 @@
#include "ui/message_center/views/message_center_bubble.h"
+#include "grit/ui_strings.h"
+#include "ui/base/l10n/l10n_util.h"
#include "ui/message_center/message_center_style.h"
-#include "ui/message_center/message_center_util.h"
#include "ui/message_center/views/message_center_view.h"
#include "ui/views/layout/fill_layout.h"
#include "ui/views/widget/widget.h"
@@ -21,7 +22,7 @@ class ContentsView : public views::View {
virtual ~ContentsView();
// Overridden from views::View:
- virtual int GetHeightForWidth(int width) OVERRIDE;
+ virtual int GetHeightForWidth(int width) const OVERRIDE;
protected:
// Overridden from views::View:
@@ -42,7 +43,7 @@ ContentsView::ContentsView(MessageCenterBubble* bubble, views::View* contents)
ContentsView::~ContentsView() {
}
-int ContentsView::GetHeightForWidth(int width) {
+int ContentsView::GetHeightForWidth(int width) const {
DCHECK_EQ(1, child_count());
int contents_width = std::max(width - GetInsets().width(), 0);
int contents_height = child_at(0)->GetHeightForWidth(contents_width);
@@ -63,7 +64,8 @@ MessageCenterBubble::MessageCenterBubble(MessageCenter* message_center,
: MessageBubbleBase(message_center, tray),
message_center_view_(NULL),
initially_settings_visible_(false),
- first_item_has_no_margin_(first_item_has_no_margin) {
+ first_item_has_no_margin_(first_item_has_no_margin),
+ title_(l10n_util::GetStringUTF16(IDS_MESSAGE_CENTER_FOOTER_TITLE)) {
}
MessageCenterBubble::~MessageCenterBubble() {
@@ -97,8 +99,9 @@ void MessageCenterBubble::InitializeContents(
tray(),
max_height(),
initially_settings_visible_,
- false /* MessageCenterBubble should be used only on ChromeOS.
- Message center is never shown top down in ChromeOS. */);
+ false, /* MessageCenterBubble should be used only on ChromeOS.
+ Message center is never shown top down in ChromeOS. */
+ title_);
bubble_view()->AddChildView(new ContentsView(this, message_center_view_));
// Resize the content of the bubble view to the given bubble size. This is
// necessary in case of the bubble border forcing a bigger size then the
diff --git a/chromium/ui/message_center/views/message_center_bubble.h b/chromium/ui/message_center/views/message_center_bubble.h
index 521bf4ac8e2..1173a95393b 100644
--- a/chromium/ui/message_center/views/message_center_bubble.h
+++ b/chromium/ui/message_center/views/message_center_bubble.h
@@ -55,6 +55,8 @@ class MESSAGE_CENTER_EXPORT MessageCenterBubble
// the used anchor.
bool first_item_has_no_margin_;
+ base::string16 title_;
+
DISALLOW_COPY_AND_ASSIGN(MessageCenterBubble);
};
diff --git a/chromium/ui/message_center/views/message_center_button_bar.cc b/chromium/ui/message_center/views/message_center_button_bar.cc
index 0816ffa29b1..8008115e705 100644
--- a/chromium/ui/message_center/views/message_center_button_bar.cc
+++ b/chromium/ui/message_center/views/message_center_button_bar.cc
@@ -13,6 +13,7 @@
#include "ui/gfx/text_constants.h"
#include "ui/message_center/message_center.h"
#include "ui/message_center/message_center_style.h"
+#include "ui/message_center/message_center_tray.h"
#include "ui/message_center/notifier_settings.h"
#include "ui/message_center/views/message_center_view.h"
#include "ui/views/controls/button/button.h"
@@ -50,7 +51,7 @@ class NotificationCenterButton : public views::ToggleImageButton {
protected:
// Overridden from views::View:
- virtual gfx::Size GetPreferredSize() OVERRIDE;
+ virtual gfx::Size GetPreferredSize() const OVERRIDE;
private:
gfx::Size size_;
@@ -82,7 +83,7 @@ NotificationCenterButton::NotificationCenterButton(
gfx::Insets(1, 2, 2, 2)));
}
-gfx::Size NotificationCenterButton::GetPreferredSize() { return size_; }
+gfx::Size NotificationCenterButton::GetPreferredSize() const { return size_; }
// MessageCenterButtonBar /////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
@@ -90,17 +91,20 @@ MessageCenterButtonBar::MessageCenterButtonBar(
MessageCenterView* message_center_view,
MessageCenter* message_center,
NotifierSettingsProvider* notifier_settings_provider,
- bool settings_initially_visible)
+ bool settings_initially_visible,
+ const base::string16& title)
: message_center_view_(message_center_view),
message_center_(message_center),
+#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
+ close_bubble_button_(NULL),
+#endif
title_arrow_(NULL),
notification_label_(NULL),
button_container_(NULL),
close_all_button_(NULL),
settings_button_(NULL),
quiet_mode_button_(NULL) {
- if (get_use_acceleration_when_possible())
- SetPaintToLayer(true);
+ SetPaintToLayer(true);
set_background(
views::Background::CreateSolidBackground(kMessageCenterBackgroundColor));
@@ -117,11 +121,7 @@ MessageCenterButtonBar::MessageCenterButtonBar(
title_arrow_->SetFocusable(false);
AddChildView(title_arrow_);
- gfx::Font notification_label_font =
- ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::BaseFont);
- notification_label_ = new views::Label(
- l10n_util::GetStringUTF16(IDS_MESSAGE_CENTER_FOOTER_TITLE),
- notification_label_font);
+ notification_label_ = new views::Label(title);
notification_label_->SetAutoColorReadabilityEnabled(false);
notification_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
notification_label_->SetEnabledColor(kRegularTextColor);
@@ -170,6 +170,20 @@ MessageCenterButtonBar::MessageCenterButtonBar(
IDS_MESSAGE_CENTER_SETTINGS_BUTTON_LABEL);
button_container_->AddChildView(settings_button_);
+#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
+ close_bubble_button_ = new views::ImageButton(this);
+ close_bubble_button_->SetImage(
+ views::Button::STATE_NORMAL,
+ resource_bundle.GetImageSkiaNamed(IDR_NOTIFICATION_BUBBLE_CLOSE));
+ close_bubble_button_->SetImage(
+ views::Button::STATE_HOVERED,
+ resource_bundle.GetImageSkiaNamed(IDR_NOTIFICATION_BUBBLE_CLOSE_HOVER));
+ close_bubble_button_->SetImage(
+ views::Button::STATE_PRESSED,
+ resource_bundle.GetImageSkiaNamed(IDR_NOTIFICATION_BUBBLE_CLOSE_PRESSED));
+ AddChildView(close_bubble_button_);
+#endif
+
SetCloseAllButtonEnabled(!settings_initially_visible);
SetBackArrowVisible(settings_initially_visible);
ViewVisibilityChanged();
@@ -218,11 +232,24 @@ void MessageCenterButtonBar::ViewVisibilityChanged() {
0,
0);
+#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
+ // The close-bubble button.
+ column->AddColumn(views::GridLayout::LEADING,
+ views::GridLayout::LEADING,
+ 0.0f,
+ views::GridLayout::USE_PREF,
+ 0,
+ 0);
+#endif
+
layout->StartRow(0, 0);
if (title_arrow_->visible())
layout->AddView(title_arrow_);
layout->AddView(notification_label_);
layout->AddView(button_container_);
+#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
+ layout->AddView(close_bubble_button_);
+#endif
}
MessageCenterButtonBar::~MessageCenterButtonBar() {}
@@ -263,6 +290,10 @@ void MessageCenterButtonBar::ButtonPressed(views::Button* sender,
else
message_center()->EnterQuietModeWithExpire(base::TimeDelta::FromDays(1));
quiet_mode_button_->SetToggled(message_center()->IsQuietMode());
+#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
+ } else if (sender == close_bubble_button_) {
+ message_center_view()->tray()->HideMessageCenterBubble();
+#endif
} else {
NOTREACHED();
}
diff --git a/chromium/ui/message_center/views/message_center_button_bar.h b/chromium/ui/message_center/views/message_center_button_bar.h
index 8190e3e2cc2..bc87dbed44e 100644
--- a/chromium/ui/message_center/views/message_center_button_bar.h
+++ b/chromium/ui/message_center/views/message_center_button_bar.h
@@ -30,7 +30,8 @@ class MessageCenterButtonBar : public views::View,
MessageCenterButtonBar(MessageCenterView* message_center_view,
MessageCenter* message_center,
NotifierSettingsProvider* notifier_settings_provider,
- bool settings_initially_visible);
+ bool settings_initially_visible,
+ const base::string16& title);
virtual ~MessageCenterButtonBar();
// Enables or disables all of the buttons in the center. This is used to
@@ -63,6 +64,15 @@ class MessageCenterButtonBar : public views::View,
MessageCenterView* message_center_view_; // Weak reference.
MessageCenter* message_center_; // Weak reference.
+ // |close_bubble_button_| closes the message center bubble. This is required
+ // for desktop Linux because the status icon doesn't toggle the bubble, and
+ // close-on-deactivation is off. This is a tentative solution. Once pkotwicz
+ // Fixes the problem of focus-follow-mouse, close-on-deactivation will be
+ // back and this field will be removed. See crbug.com/319516.
+#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
+ views::ImageButton* close_bubble_button_;
+#endif
+
// Sub-views of the button bar.
NotificationCenterButton* title_arrow_;
views::Label* notification_label_;
diff --git a/chromium/ui/message_center/views/message_center_controller.h b/chromium/ui/message_center/views/message_center_controller.h
index c680c0eedb1..df413555b70 100644
--- a/chromium/ui/message_center/views/message_center_controller.h
+++ b/chromium/ui/message_center/views/message_center_controller.h
@@ -7,6 +7,9 @@
#include <string>
+#include "base/memory/scoped_ptr.h"
+#include "base/strings/string16.h"
+#include "ui/base/models/menu_model.h"
#include "ui/message_center/notifier_settings.h"
namespace message_center {
@@ -20,18 +23,14 @@ class MessageCenterController {
virtual void ClickOnNotification(const std::string& notification_id) = 0;
virtual void RemoveNotification(const std::string& notification_id,
bool by_user) = 0;
- virtual void DisableNotificationsFromThisSource(
- const NotifierId& notifier_id) = 0;
- virtual void ShowNotifierSettingsBubble() = 0;
+ virtual scoped_ptr<ui::MenuModel> CreateMenuModel(
+ const NotifierId& notifier_id,
+ const base::string16& display_source) = 0;
virtual bool HasClickedListener(const std::string& notification_id) = 0;
virtual void ClickOnNotificationButton(const std::string& notification_id,
int button_index) = 0;
- virtual void ExpandNotification(const std::string& notification_id) = 0;
- virtual void GroupBodyClicked(const std::string& last_notification_id) = 0;
- virtual void ExpandGroup(const NotifierId& notifier_id) = 0;
- virtual void RemoveGroup(const NotifierId& notifier_id) = 0;
};
} // namespace message_center
-#endif // UI_MESSAGE_CENTER_VIEWS_MESSAGE_CENTER_CONTROLLER_H_ \ No newline at end of file
+#endif // UI_MESSAGE_CENTER_VIEWS_MESSAGE_CENTER_CONTROLLER_H_
diff --git a/chromium/ui/message_center/views/message_center_view.cc b/chromium/ui/message_center/views/message_center_view.cc
index ebdbf33b2d6..0f003ed050b 100644
--- a/chromium/ui/message_center/views/message_center_view.cc
+++ b/chromium/ui/message_center/views/message_center_view.cc
@@ -24,10 +24,9 @@
#include "ui/message_center/message_center_style.h"
#include "ui/message_center/message_center_tray.h"
#include "ui/message_center/message_center_types.h"
-#include "ui/message_center/message_center_util.h"
-#include "ui/message_center/views/group_view.h"
#include "ui/message_center/views/message_center_button_bar.h"
#include "ui/message_center/views/message_view.h"
+#include "ui/message_center/views/message_view_context_menu_controller.h"
#include "ui/message_center/views/notification_view.h"
#include "ui/message_center/views/notifier_settings_view.h"
#include "ui/views/animation/bounds_animator.h"
@@ -51,80 +50,19 @@ const SkColor kNoNotificationsTextColor = SkColorSetRGB(0xb4, 0xb4, 0xb4);
const SkColor kTransparentColor = SkColorSetARGB(0, 0, 0, 0);
#endif
const int kAnimateClearingNextNotificationDelayMS = 40;
-const int kMinScrollViewHeight = 100;
const int kDefaultAnimationDurationMs = 120;
const int kDefaultFrameRateHz = 60;
-
-const int kMaxNotificationCountFromSingleDisplaySource = 1;
-
} // namespace
-// BoundedScrollView ///////////////////////////////////////////////////////////
-
-// A custom scroll view whose height has a minimum and maximum value and whose
-// scroll bar disappears when not needed.
-class BoundedScrollView : public views::ScrollView {
- public:
- BoundedScrollView(int min_height, int max_height);
-
- // Overridden from views::View:
- virtual gfx::Size GetPreferredSize() OVERRIDE;
- virtual int GetHeightForWidth(int width) OVERRIDE;
- virtual void Layout() OVERRIDE;
-
- private:
- int min_height_;
- int max_height_;
-
- DISALLOW_COPY_AND_ASSIGN(BoundedScrollView);
-};
-
-BoundedScrollView::BoundedScrollView(int min_height, int max_height)
- : min_height_(min_height),
- max_height_(max_height) {
- set_notify_enter_exit_on_child(true);
- set_background(
- views::Background::CreateSolidBackground(kMessageCenterBackgroundColor));
- SetVerticalScrollBar(new views::OverlayScrollBar(false));
-}
-
-gfx::Size BoundedScrollView::GetPreferredSize() {
- gfx::Size size = contents()->GetPreferredSize();
- size.SetToMax(gfx::Size(size.width(), min_height_));
- size.SetToMin(gfx::Size(size.width(), max_height_));
- gfx::Insets insets = GetInsets();
- size.Enlarge(insets.width(), insets.height());
- return size;
-}
-
-int BoundedScrollView::GetHeightForWidth(int width) {
- gfx::Insets insets = GetInsets();
- width = std::max(0, width - insets.width());
- int height = contents()->GetHeightForWidth(width) + insets.height();
- return std::min(std::max(height, min_height_), max_height_);
-}
-
-void BoundedScrollView::Layout() {
- int content_width = width();
- int content_height = contents()->GetHeightForWidth(content_width);
- if (content_height > height()) {
- content_width = std::max(content_width - GetScrollBarWidth(), 0);
- content_height = contents()->GetHeightForWidth(content_width);
- }
- if (contents()->bounds().size() != gfx::Size(content_width, content_height))
- contents()->SetBounds(0, 0, content_width, content_height);
- views::ScrollView::Layout();
-}
-
class NoNotificationMessageView : public views::View {
public:
NoNotificationMessageView();
virtual ~NoNotificationMessageView();
// Overridden from views::View.
- virtual gfx::Size GetPreferredSize() OVERRIDE;
- virtual int GetHeightForWidth(int width) OVERRIDE;
+ virtual gfx::Size GetPreferredSize() const OVERRIDE;
+ virtual int GetHeightForWidth(int width) const OVERRIDE;
virtual void Layout() OVERRIDE;
private:
@@ -149,11 +87,11 @@ NoNotificationMessageView::NoNotificationMessageView() {
NoNotificationMessageView::~NoNotificationMessageView() {
}
-gfx::Size NoNotificationMessageView::GetPreferredSize() {
+gfx::Size NoNotificationMessageView::GetPreferredSize() const {
return gfx::Size(kMinScrollViewHeight, label_->GetPreferredSize().width());
}
-int NoNotificationMessageView::GetHeightForWidth(int width) {
+int NoNotificationMessageView::GetHeightForWidth(int width) const {
return kMinScrollViewHeight;
}
@@ -174,8 +112,8 @@ class MessageListView : public views::View,
virtual ~MessageListView();
void AddNotificationAt(MessageView* view, int i);
- void RemoveNotificationAt(int i);
- void UpdateNotificationAt(MessageView* view, int i);
+ void RemoveNotification(MessageView* view);
+ void UpdateNotification(MessageView* view, const Notification& notification);
void SetRepositionTarget(const gfx::Rect& target_rect);
void ResetRepositionSession();
void ClearAllNotifications(const gfx::Rect& visible_scroll_rect);
@@ -183,9 +121,10 @@ class MessageListView : public views::View,
protected:
// Overridden from views::View.
virtual void Layout() OVERRIDE;
- virtual gfx::Size GetPreferredSize() OVERRIDE;
- virtual int GetHeightForWidth(int width) OVERRIDE;
- virtual void PaintChildren(gfx::Canvas* canvas) OVERRIDE;
+ virtual gfx::Size GetPreferredSize() const OVERRIDE;
+ virtual int GetHeightForWidth(int width) const OVERRIDE;
+ virtual void PaintChildren(gfx::Canvas* canvas,
+ const views::CullSet& cull_set) OVERRIDE;
virtual void ReorderChildLayers(ui::Layer* parent_layer) OVERRIDE;
// Overridden from views::BoundsAnimatorObserver.
@@ -194,14 +133,7 @@ class MessageListView : public views::View,
virtual void OnBoundsAnimatorDone(views::BoundsAnimator* animator) OVERRIDE;
private:
- // Returns the actual index for child of |index|.
- // MessageListView allows to slide down upper notifications, which means
- // that the upper ones should come above the lower ones if top_down is not
- // enabled. To achieve this, inversed order is adopted. The top most
- // notification is the last child, and the bottom most notification is the
- // first child.
- int GetActualIndex(int index);
- bool IsValidChild(views::View* child);
+ bool IsValidChild(const views::View* child) const;
void DoUpdateIfPossible();
// Animates all notifications below target upwards to align with the top of
@@ -249,7 +181,7 @@ MessageListView::MessageListView(MessageCenterView* message_center_view,
weak_ptr_factory_(this) {
views::BoxLayout* layout =
new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 1);
- layout->set_spread_blank_space(true);
+ layout->set_main_axis_alignment(views::BoxLayout::MAIN_AXIS_ALIGNMENT_FILL);
SetLayoutManager(layout);
// Set the margin to 0 for the layout. BoxLayout assumes the same margin
@@ -259,7 +191,7 @@ MessageListView::MessageListView(MessageCenterView* message_center_view,
gfx::Insets shadow_insets = MessageView::GetShadowInsets();
set_background(views::Background::CreateSolidBackground(
kMessageCenterBackgroundColor));
- set_border(views::Border::CreateEmptyBorder(
+ SetBorder(views::Border::CreateEmptyBorder(
top_down ? 0 : kMarginBetweenItems - shadow_insets.top(), /* top */
kMarginBetweenItems - shadow_insets.left(), /* left */
top_down ? kMarginBetweenItems - shadow_insets.bottom() : 0, /* bottom */
@@ -290,8 +222,22 @@ void MessageListView::Layout() {
}
}
-void MessageListView::AddNotificationAt(MessageView* view, int i) {
- AddChildViewAt(view, GetActualIndex(i));
+void MessageListView::AddNotificationAt(MessageView* view, int index) {
+ // |index| refers to a position in a subset of valid children. |real_index|
+ // in a list includes the invalid children, so we compute the real index by
+ // walking the list until |index| number of valid children are encountered,
+ // or to the end of the list.
+ int real_index = 0;
+ while (real_index < child_count()) {
+ if (IsValidChild(child_at(real_index))) {
+ --index;
+ if (index < 0)
+ break;
+ }
+ ++real_index;
+ }
+
+ AddChildViewAt(view, real_index);
if (GetContentsBounds().IsEmpty())
return;
@@ -299,43 +245,41 @@ void MessageListView::AddNotificationAt(MessageView* view, int i) {
DoUpdateIfPossible();
}
-void MessageListView::RemoveNotificationAt(int i) {
- views::View* child = child_at(GetActualIndex(i));
+void MessageListView::RemoveNotification(MessageView* view) {
+ DCHECK_EQ(view->parent(), this);
if (GetContentsBounds().IsEmpty()) {
- delete child;
+ delete view;
} else {
- if (child->layer()) {
- deleting_views_.insert(child);
+ if (view->layer()) {
+ deleting_views_.insert(view);
} else {
if (animator_.get())
- animator_->StopAnimatingView(child);
- delete child;
+ animator_->StopAnimatingView(view);
+ delete view;
}
DoUpdateIfPossible();
}
}
-void MessageListView::UpdateNotificationAt(MessageView* view, int i) {
- int actual_index = GetActualIndex(i);
- views::View* child = child_at(actual_index);
+void MessageListView::UpdateNotification(MessageView* view,
+ const Notification& notification) {
+ int index = GetIndexOf(view);
+ DCHECK_LE(0, index); // GetIndexOf is negative if not a child.
+
if (animator_.get())
- animator_->StopAnimatingView(child);
- gfx::Rect old_bounds = child->bounds();
- if (deleting_views_.find(child) != deleting_views_.end())
- deleting_views_.erase(child);
- if (deleted_when_done_.find(child) != deleted_when_done_.end())
- deleted_when_done_.erase(child);
- delete child;
- AddChildViewAt(view, actual_index);
- view->SetBounds(old_bounds.x(), old_bounds.y(), old_bounds.width(),
- view->GetHeightForWidth(old_bounds.width()));
+ animator_->StopAnimatingView(view);
+ if (deleting_views_.find(view) != deleting_views_.end())
+ deleting_views_.erase(view);
+ if (deleted_when_done_.find(view) != deleted_when_done_.end())
+ deleted_when_done_.erase(view);
+ view->UpdateWithNotification(notification);
DoUpdateIfPossible();
}
-gfx::Size MessageListView::GetPreferredSize() {
+gfx::Size MessageListView::GetPreferredSize() const {
int width = 0;
for (int i = 0; i < child_count(); i++) {
- views::View* child = child_at(i);
+ const views::View* child = child_at(i);
if (IsValidChild(child))
width = std::max(width, child->GetPreferredSize().width());
}
@@ -344,7 +288,7 @@ gfx::Size MessageListView::GetPreferredSize() {
GetHeightForWidth(width + GetInsets().width()));
}
-int MessageListView::GetHeightForWidth(int width) {
+int MessageListView::GetHeightForWidth(int width) const {
if (fixed_height_ > 0)
return fixed_height_;
@@ -352,7 +296,7 @@ int MessageListView::GetHeightForWidth(int width) {
int height = 0;
int padding = 0;
for (int i = 0; i < child_count(); ++i) {
- views::View* child = child_at(i);
+ const views::View* child = child_at(i);
if (!IsValidChild(child))
continue;
height += child->GetHeightForWidth(width) + padding;
@@ -362,12 +306,13 @@ int MessageListView::GetHeightForWidth(int width) {
return height + GetInsets().height();
}
-void MessageListView::PaintChildren(gfx::Canvas* canvas) {
+void MessageListView::PaintChildren(gfx::Canvas* canvas,
+ const views::CullSet& cull_set) {
// Paint in the inversed order. Otherwise upper notification may be
// hidden by the lower one.
for (int i = child_count() - 1; i >= 0; --i) {
if (!child_at(i)->layer())
- child_at(i)->Paint(canvas);
+ child_at(i)->Paint(canvas, cull_set);
}
}
@@ -446,16 +391,12 @@ void MessageListView::OnBoundsAnimatorDone(views::BoundsAnimator* animator) {
GetWidget()->SynthesizeMouseMoveEvent();
}
-int MessageListView::GetActualIndex(int index) {
- for (int i = 0; i < child_count() && i <= index; ++i)
- index += IsValidChild(child_at(i)) ? 0 : 1;
- return std::min(index, child_count());
-}
-
-bool MessageListView::IsValidChild(views::View* child) {
+bool MessageListView::IsValidChild(const views::View* child) const {
return child->visible() &&
- deleting_views_.find(child) == deleting_views_.end() &&
- deleted_when_done_.find(child) == deleted_when_done_.end();
+ deleting_views_.find(const_cast<views::View*>(child)) ==
+ deleting_views_.end() &&
+ deleted_when_done_.find(const_cast<views::View*>(child)) ==
+ deleted_when_done_.end();
}
void MessageListView::DoUpdateIfPossible() {
@@ -594,7 +535,8 @@ MessageCenterView::MessageCenterView(MessageCenter* message_center,
MessageCenterTray* tray,
int max_height,
bool initially_settings_visible,
- bool top_down)
+ bool top_down,
+ const base::string16& title)
: message_center_(message_center),
tray_(tray),
scroller_(NULL),
@@ -606,7 +548,8 @@ MessageCenterView::MessageCenterView(MessageCenter* message_center,
source_height_(0),
target_view_(NULL),
target_height_(0),
- is_closing_(false) {
+ is_closing_(false),
+ context_menu_controller_(new MessageViewContextMenuController(this)) {
message_center_->AddObserver(this);
set_notify_enter_exit_on_child(true);
set_background(views::Background::CreateSolidBackground(
@@ -617,18 +560,20 @@ MessageCenterView::MessageCenterView(MessageCenter* message_center,
button_bar_ = new MessageCenterButtonBar(this,
message_center,
notifier_settings_provider,
- initially_settings_visible);
+ initially_settings_visible,
+ title);
const int button_height = button_bar_->GetPreferredSize().height();
- scroller_ =
- new BoundedScrollView(kMinScrollViewHeight, max_height - button_height);
+ scroller_ = new views::ScrollView();
+ scroller_->ClipHeightTo(kMinScrollViewHeight, max_height - button_height);
+ scroller_->SetVerticalScrollBar(new views::OverlayScrollBar(false));
+ scroller_->set_background(
+ views::Background::CreateSolidBackground(kMessageCenterBackgroundColor));
- if (get_use_acceleration_when_possible()) {
- scroller_->SetPaintToLayer(true);
- scroller_->SetFillsBoundsOpaquely(false);
- scroller_->layer()->SetMasksToBounds(true);
- }
+ scroller_->SetPaintToLayer(true);
+ scroller_->SetFillsBoundsOpaquely(false);
+ scroller_->layer()->SetMasksToBounds(true);
empty_list_view_.reset(new NoNotificationMessageView);
empty_list_view_->set_owned_by_client();
@@ -670,65 +615,15 @@ void MessageCenterView::SetNotifications(
notification_views_.clear();
- // Count how many times each Notifier is encountered. We group Notifications
- // by NotifierId.
- std::map<NotifierId, int> groups;
int index = 0;
+ for (NotificationList::Notifications::const_iterator iter =
+ notifications.begin(); iter != notifications.end(); ++iter) {
+ AddNotificationAt(*(*iter), index++);
- if (IsExperimentalNotificationUIEnabled()) {
- for (NotificationList::Notifications::const_iterator iter =
- notifications.begin(); iter != notifications.end(); ++iter) {
- NotifierId group_id = (*iter)->notifier_id();
- std::map<NotifierId, int>::iterator group_iter = groups.find(group_id);
- if (group_iter != groups.end())
- group_iter->second++;
- else
- groups[group_id] = 1;
- }
-
- // TODO(dimich): Find a better group icon. Preferably associated with
- // the group (notifier icon?).
- gfx::ImageSkia* group_icon = ui::ResourceBundle::GetSharedInstance().
- GetImageSkiaNamed(IDR_FOLDER_CLOSED);
-
- for (NotificationList::Notifications::const_iterator iter =
- notifications.begin(); iter != notifications.end(); ++iter) {
- // See if the notification's NotifierId is encountered too many
- // times - in this case replace all notifications from this source with
- // a synthetic placeholder that says "N more". Mark the NotifierId
- // as "seen" by setting count to 0 so the subsequent notificaitons from
- // the same source are ignored.
- std::map<NotifierId, int>::iterator group_iter =
- groups.find((*iter)->notifier_id());
- // We should have collected all groups in the loop above.
- DCHECK(group_iter != groups.end());
-
- if (group_iter->second > kMaxNotificationCountFromSingleDisplaySource) {
- AddGroupPlaceholder(group_iter->first,
- *(*iter),
- group_icon ? *group_icon : gfx::ImageSkia(),
- group_iter->second,
- index++);
- group_iter->second = 0; // Mark.
- } else if (group_iter->second == 0) { // Marked, skip.
- continue;
- } else { // Ungrouped notifications
- AddNotificationAt(*(*iter), index++);
- }
-
- message_center_->DisplayedNotification((*iter)->id());
- if (notification_views_.size() >= kMaxVisibleMessageCenterNotifications)
- break;
- }
- } else {
- for (NotificationList::Notifications::const_iterator iter =
- notifications.begin(); iter != notifications.end(); ++iter) {
- AddNotificationAt(*(*iter), index++);
-
- message_center_->DisplayedNotification((*iter)->id());
- if (notification_views_.size() >= kMaxVisibleMessageCenterNotifications)
- break;
- }
+ message_center_->DisplayedNotification(
+ (*iter)->id(), message_center::DISPLAY_SOURCE_MESSAGE_CENTER);
+ if (notification_views_.size() >= kMaxVisibleMessageCenterNotifications)
+ break;
}
NotificationsChanged();
@@ -854,10 +749,10 @@ void MessageCenterView::Layout() {
if (is_scrollable) {
// Draw separator line on the top of the button bar if it is on the bottom
// or draw it at the bottom if the bar is on the top.
- button_bar_->set_border(views::Border::CreateSolidSidedBorder(
+ button_bar_->SetBorder(views::Border::CreateSolidSidedBorder(
top_down_ ? 0 : 1, 0, top_down_ ? 1 : 0, 0, kFooterDelimiterColor));
} else {
- button_bar_->set_border(views::Border::CreateEmptyBorder(
+ button_bar_->SetBorder(views::Border::CreateEmptyBorder(
top_down_ ? 0 : 1, 0, top_down_ ? 1 : 0, 0));
}
button_bar_->SchedulePaint();
@@ -870,7 +765,7 @@ void MessageCenterView::Layout() {
GetWidget()->GetRootView()->SchedulePaint();
}
-gfx::Size MessageCenterView::GetPreferredSize() {
+gfx::Size MessageCenterView::GetPreferredSize() const {
if (settings_transition_animation_ &&
settings_transition_animation_->is_animating()) {
int content_width = std::max(source_view_->GetPreferredSize().width(),
@@ -882,14 +777,14 @@ gfx::Size MessageCenterView::GetPreferredSize() {
int width = 0;
for (int i = 0; i < child_count(); ++i) {
- views::View* child = child_at(0);
+ const views::View* child = child_at(0);
if (child->visible())
width = std::max(width, child->GetPreferredSize().width());
}
return gfx::Size(width, GetHeightForWidth(width));
}
-int MessageCenterView::GetHeightForWidth(int width) {
+int MessageCenterView::GetHeightForWidth(int width) const {
if (settings_transition_animation_ &&
settings_transition_animation_->is_animating()) {
int content_height = target_height_;
@@ -927,7 +822,6 @@ void MessageCenterView::OnMouseExited(const ui::MouseEvent& event) {
NotificationsChanged();
}
-// TODO(dimich): update for GROUP_VIEW
void MessageCenterView::OnNotificationAdded(const std::string& id) {
int index = 0;
const NotificationList::Notifications& notifications =
@@ -945,7 +839,6 @@ void MessageCenterView::OnNotificationAdded(const std::string& id) {
NotificationsChanged();
}
-// TODO(dimich): update for GROUP_VIEW
void MessageCenterView::OnNotificationRemoved(const std::string& id,
bool by_user) {
NotificationViewsMap::iterator view_iter = notification_views_.find(id);
@@ -953,6 +846,7 @@ void MessageCenterView::OnNotificationRemoved(const std::string& id,
return;
NotificationView* view = view_iter->second;
int index = message_list_view_->GetIndexOf(view);
+ DCHECK_LE(0, index);
if (by_user) {
message_list_view_->SetRepositionTarget(view->bounds());
// Moves the keyboard focus to the next notification if the removed
@@ -976,38 +870,27 @@ void MessageCenterView::OnNotificationRemoved(const std::string& id,
}
}
}
- message_list_view_->RemoveNotificationAt(index);
+ message_list_view_->RemoveNotification(view);
notification_views_.erase(view_iter);
NotificationsChanged();
}
-// TODO(dimich): update for GROUP_VIEW
void MessageCenterView::OnNotificationUpdated(const std::string& id) {
NotificationViewsMap::const_iterator view_iter = notification_views_.find(id);
if (view_iter == notification_views_.end())
return;
NotificationView* view = view_iter->second;
- size_t index = message_list_view_->GetIndexOf(view);
- DCHECK(index >= 0);
// TODO(dimich): add MessageCenter::GetVisibleNotificationById(id)
const NotificationList::Notifications& notifications =
message_center_->GetVisibleNotifications();
for (NotificationList::Notifications::const_iterator iter =
notifications.begin(); iter != notifications.end(); ++iter) {
if ((*iter)->id() == id) {
- bool expanded = true;
- if (IsExperimentalNotificationUIEnabled())
- expanded = (*iter)->is_expanded();
- NotificationView* view =
- NotificationView::Create(this,
- *(*iter),
- expanded,
- false); // Not creating a top-level
- // notification.
- view->set_scroller(scroller_);
- message_list_view_->UpdateNotificationAt(view, index);
- notification_views_[id] = view;
- NotificationsChanged();
+ int old_width = view->width();
+ int old_height = view->GetHeightForWidth(old_width);
+ message_list_view_->UpdateNotification(view, **iter);
+ if (view->GetHeightForWidth(old_width) != old_height)
+ NotificationsChanged();
break;
}
}
@@ -1023,13 +906,10 @@ void MessageCenterView::RemoveNotification(const std::string& notification_id,
message_center_->RemoveNotification(notification_id, by_user);
}
-void MessageCenterView::DisableNotificationsFromThisSource(
- const NotifierId& notifier_id) {
- message_center_->DisableNotificationsByNotifier(notifier_id);
-}
-
-void MessageCenterView::ShowNotifierSettingsBubble() {
- tray_->ShowNotifierSettingsBubble();
+scoped_ptr<ui::MenuModel> MessageCenterView::CreateMenuModel(
+ const NotifierId& notifier_id,
+ const base::string16& display_source) {
+ return tray_->CreateNotificationMenuModel(notifier_id, display_source);
}
bool MessageCenterView::HasClickedListener(const std::string& notification_id) {
@@ -1042,41 +922,6 @@ void MessageCenterView::ClickOnNotificationButton(
message_center_->ClickOnNotificationButton(notification_id, button_index);
}
-void MessageCenterView::ExpandNotification(const std::string& notification_id) {
- message_center_->ExpandNotification(notification_id);
-}
-
-void MessageCenterView::GroupBodyClicked(
- const std::string& last_notification_id) {
- message_center_->ClickOnNotification(last_notification_id);
-}
-
-// When clicked on the "N more" button, perform some reasonable action.
-// TODO(dimich): find out what the reasonable action could be.
-void MessageCenterView::ExpandGroup(const NotifierId& notifier_id) {
- NOTIMPLEMENTED();
-}
-
-// Click on Close button on a GroupView should remove all notifications
-// represented by this GroupView.
-void MessageCenterView::RemoveGroup(const NotifierId& notifier_id) {
- std::vector<std::string> notifications_to_remove;
-
- // Can not remove notifications while iterating the list. Collect the ids
- // and then run separate loop to remove notifications.
- const NotificationList::Notifications& notifications =
- message_center_->GetVisibleNotifications();
- for (NotificationList::Notifications::const_iterator iter =
- notifications.begin(); iter != notifications.end(); ++iter) {
- if ((*iter)->notifier_id() == notifier_id)
- notifications_to_remove.push_back((*iter)->id());
- }
-
- for (size_t i = 0; i < notifications_to_remove.size(); ++i)
- // "by_user" = true
- message_center_->RemoveNotification(notifications_to_remove[i], true);
-}
-
void MessageCenterView::AnimationEnded(const gfx::Animation* animation) {
DCHECK_EQ(animation, settings_transition_animation_.get());
@@ -1117,46 +962,18 @@ void MessageCenterView::AnimationCanceled(const gfx::Animation* animation) {
AnimationEnded(animation);
}
-
-void MessageCenterView::AddMessageViewAt(MessageView* view, int index) {
- view->set_scroller(scroller_);
- message_list_view_->AddNotificationAt(view, index);
-}
-
-void MessageCenterView::AddGroupPlaceholder(
- const NotifierId& group_id,
- const Notification& last_notification,
- const gfx::ImageSkia& group_icon,
- int group_size,
- int index) {
- GroupView* view = new GroupView(this,
- group_id,
- last_notification,
- group_icon,
- group_size);
- group_views_.push_back(view);
- AddMessageViewAt(view, index);
-}
-
void MessageCenterView::AddNotificationAt(const Notification& notification,
int index) {
- // NotificationViews are expanded by default here until
- // http://crbug.com/217902 is fixed. TODO(dharcourt): Fix.
- bool expanded = true;
- if (IsExperimentalNotificationUIEnabled())
- expanded = notification.is_expanded();
NotificationView* view =
- NotificationView::Create(this,
- notification,
- expanded,
- false); // Not creating a top-level
- // notification.
+ NotificationView::Create(this, notification, false); // Not top-level.
+ view->set_context_menu_controller(context_menu_controller_.get());
notification_views_[notification.id()] = view;
- AddMessageViewAt(view, index);
+ view->set_scroller(scroller_);
+ message_list_view_->AddNotificationAt(view, index);
}
void MessageCenterView::NotificationsChanged() {
- bool no_message_views = notification_views_.empty() && group_views_.empty();
+ bool no_message_views = notification_views_.empty();
// When the child view is removed from the hierarchy, its focus is cleared.
// In this case we want to save which view has focus so that the user can
diff --git a/chromium/ui/message_center/views/message_center_view.h b/chromium/ui/message_center/views/message_center_view.h
index b64f770a8e6..94dd139213c 100644
--- a/chromium/ui/message_center/views/message_center_view.h
+++ b/chromium/ui/message_center/views/message_center_view.h
@@ -5,7 +5,6 @@
#ifndef UI_MESSAGE_CENTER_VIEWS_MESSAGE_CENTER_VIEW_H_
#define UI_MESSAGE_CENTER_VIEWS_MESSAGE_CENTER_VIEW_H_
-#include "ui/views/view.h"
#include "ui/gfx/animation/animation_delegate.h"
#include "ui/message_center/message_center_export.h"
@@ -14,6 +13,7 @@
#include "ui/message_center/views/message_center_controller.h"
#include "ui/message_center/views/message_view.h"
#include "ui/views/controls/button/button.h"
+#include "ui/views/view.h"
namespace gfx {
class MultiAnimation;
@@ -25,7 +25,6 @@ class Button;
namespace message_center {
-class GroupView;
class MessageCenter;
class MessageCenterBubble;
class NotificationCenterButton;
@@ -33,6 +32,7 @@ class MessageCenterButtonBar;
class MessageCenterTray;
class MessageCenterView;
class MessageView;
+class MessageViewContextMenuController;
class MessageListView;
class NotificationView;
class NotifierSettingsView;
@@ -48,7 +48,8 @@ class MESSAGE_CENTER_EXPORT MessageCenterView : public views::View,
MessageCenterTray* tray,
int max_height,
bool initially_settings_visible,
- bool top_down);
+ bool top_down,
+ const base::string16& title);
virtual ~MessageCenterView();
void SetNotifications(const NotificationList::Notifications& notifications);
@@ -61,14 +62,15 @@ class MESSAGE_CENTER_EXPORT MessageCenterView : public views::View,
void SetSettingsVisible(bool visible);
void OnSettingsChanged();
bool settings_visible() const { return settings_visible_; }
+ MessageCenterTray* tray() { return tray_; }
void SetIsClosing(bool is_closing);
protected:
// Overridden from views::View:
virtual void Layout() OVERRIDE;
- virtual gfx::Size GetPreferredSize() OVERRIDE;
- virtual int GetHeightForWidth(int width) OVERRIDE;
+ virtual gfx::Size GetPreferredSize() const OVERRIDE;
+ virtual int GetHeightForWidth(int width) const OVERRIDE;
virtual bool OnMouseWheel(const ui::MouseWheelEvent& event) OVERRIDE;
virtual void OnMouseExited(const ui::MouseEvent& event) OVERRIDE;
@@ -82,17 +84,12 @@ class MESSAGE_CENTER_EXPORT MessageCenterView : public views::View,
virtual void ClickOnNotification(const std::string& notification_id) OVERRIDE;
virtual void RemoveNotification(const std::string& notification_id,
bool by_user) OVERRIDE;
- virtual void DisableNotificationsFromThisSource(
- const NotifierId& notifier_id) OVERRIDE;
- virtual void ShowNotifierSettingsBubble() OVERRIDE;
+ virtual scoped_ptr<ui::MenuModel> CreateMenuModel(
+ const NotifierId& notifier_id,
+ const base::string16& display_source) OVERRIDE;
virtual bool HasClickedListener(const std::string& notification_id) OVERRIDE;
virtual void ClickOnNotificationButton(const std::string& notification_id,
int button_index) OVERRIDE;
- virtual void ExpandNotification(const std::string& notification_id) OVERRIDE;
- virtual void GroupBodyClicked(const std::string& last_notification_id)
- OVERRIDE;
- virtual void ExpandGroup(const NotifierId& notifier_id) OVERRIDE;
- virtual void RemoveGroup(const NotifierId& notifier_id) OVERRIDE;
// Overridden from gfx::AnimationDelegate:
virtual void AnimationEnded(const gfx::Animation* animation) OVERRIDE;
@@ -102,12 +99,6 @@ class MESSAGE_CENTER_EXPORT MessageCenterView : public views::View,
private:
friend class MessageCenterViewTest;
- void AddMessageViewAt(MessageView* view, int index);
- void AddGroupPlaceholder(const NotifierId& group_id,
- const Notification& notification,
- const gfx::ImageSkia& group_icon,
- int group_size,
- int index);
void AddNotificationAt(const Notification& notification, int index);
void NotificationsChanged();
void SetNotificationViewForTest(MessageView* view);
@@ -115,16 +106,11 @@ class MESSAGE_CENTER_EXPORT MessageCenterView : public views::View,
MessageCenter* message_center_; // Weak reference.
MessageCenterTray* tray_; // Weak reference.
- // Map notification_id->NotificationView*. It contains all NotificaitonViews
+ // Map notification_id->NotificationView*. It contains all NotificationViews
// currently displayed in MessageCenter.
typedef std::map<std::string, NotificationView*> NotificationViewsMap;
NotificationViewsMap notification_views_; // Weak.
- // List of all GroupViews. GroupView is responsible for multiple Notifications
- // from the same source.
- typedef std::list<GroupView*> GroupViews;
- GroupViews group_views_; // Weak.
-
// Child views.
views::ScrollView* scroller_;
scoped_ptr<MessageListView> message_list_view_;
@@ -151,6 +137,8 @@ class MESSAGE_CENTER_EXPORT MessageCenterView : public views::View,
// ignored.
bool is_closing_;
+ scoped_ptr<MessageViewContextMenuController> context_menu_controller_;
+
DISALLOW_COPY_AND_ASSIGN(MessageCenterView);
};
diff --git a/chromium/ui/message_center/views/message_center_view_unittest.cc b/chromium/ui/message_center/views/message_center_view_unittest.cc
index cd44e2dec66..3335ed8c52b 100644
--- a/chromium/ui/message_center/views/message_center_view_unittest.cc
+++ b/chromium/ui/message_center/views/message_center_view_unittest.cc
@@ -40,8 +40,8 @@ class MockNotificationView : public NotificationView {
Test* test);
virtual ~MockNotificationView();
- virtual gfx::Size GetPreferredSize() OVERRIDE;
- virtual int GetHeightForWidth(int w) OVERRIDE;
+ virtual gfx::Size GetPreferredSize() const OVERRIDE;
+ virtual int GetHeightForWidth(int w) const OVERRIDE;
virtual void Layout() OVERRIDE;
private:
@@ -53,20 +53,20 @@ class MockNotificationView : public NotificationView {
MockNotificationView::MockNotificationView(MessageCenterController* controller,
const Notification& notification,
Test* test)
- : NotificationView(controller, notification, true),
+ : NotificationView(controller, notification),
test_(test) {
}
MockNotificationView::~MockNotificationView() {
}
-gfx::Size MockNotificationView::GetPreferredSize() {
+gfx::Size MockNotificationView::GetPreferredSize() const {
test_->RegisterCall(GET_PREFERRED_SIZE);
DCHECK(child_count() > 0);
return NotificationView::GetPreferredSize();
}
-int MockNotificationView::GetHeightForWidth(int width) {
+int MockNotificationView::GetHeightForWidth(int width) const {
test_->RegisterCall(GET_HEIGHT_FOR_WIDTH);
DCHECK(child_count() > 0);
return NotificationView::GetHeightForWidth(width);
@@ -98,17 +98,12 @@ class MessageCenterViewTest : public testing::Test,
virtual void ClickOnNotification(const std::string& notification_id) OVERRIDE;
virtual void RemoveNotification(const std::string& notification_id,
bool by_user) OVERRIDE;
- virtual void DisableNotificationsFromThisSource(
- const NotifierId& notifier_id) OVERRIDE;
- virtual void ShowNotifierSettingsBubble() OVERRIDE;
+ virtual scoped_ptr<ui::MenuModel> CreateMenuModel(
+ const NotifierId& notifier_id,
+ const base::string16& display_source) OVERRIDE;
virtual bool HasClickedListener(const std::string& notification_id) OVERRIDE;
virtual void ClickOnNotificationButton(const std::string& notification_id,
int button_index) OVERRIDE;
- virtual void ExpandNotification(const std::string& notification_id) OVERRIDE;
- virtual void GroupBodyClicked(const std::string& last_notification_id)
- OVERRIDE;
- virtual void ExpandGroup(const NotifierId& notifier_id) OVERRIDE;
- virtual void RemoveGroup(const NotifierId& notifier_id) OVERRIDE;
// Overridden from MockNotificationView::Test
virtual void RegisterCall(CallType type) OVERRIDE;
@@ -136,10 +131,10 @@ void MessageCenterViewTest::SetUp() {
// Create a dummy notification.
Notification notification(NOTIFICATION_TYPE_SIMPLE,
std::string("notification id"),
- UTF8ToUTF16("title"),
- UTF8ToUTF16("message"),
+ base::UTF8ToUTF16("title"),
+ base::UTF8ToUTF16("message"),
gfx::Image(),
- UTF8ToUTF16("display source"),
+ base::UTF8ToUTF16("display source"),
NotifierId(NotifierId::APPLICATION, "extension_id"),
message_center::RichNotificationData(),
NULL);
@@ -149,8 +144,9 @@ void MessageCenterViewTest::SetUp() {
notifications.insert(&notification);
// Then create a new MessageCenterView with that single notification.
+ base::string16 title;
message_center_view_.reset(new MessageCenterView(
- &message_center_, NULL, 100, false, /*top_down =*/false));
+ &message_center_, NULL, 100, false, /*top_down =*/false, title));
message_center_view_->SetNotifications(notifications);
// Remove and delete the NotificationView now owned by the MessageCenterView's
@@ -191,15 +187,12 @@ void MessageCenterViewTest::RemoveNotification(
NOTREACHED();
}
-void MessageCenterViewTest::DisableNotificationsFromThisSource(
- const NotifierId& notifier_id) {
- // For this test, this method should not be invoked.
- NOTREACHED();
-}
-
-void MessageCenterViewTest::ShowNotifierSettingsBubble() {
+scoped_ptr<ui::MenuModel> MessageCenterViewTest::CreateMenuModel(
+ const NotifierId& notifier_id,
+ const base::string16& display_source) {
// For this test, this method should not be invoked.
NOTREACHED();
+ return scoped_ptr<ui::MenuModel>();
}
bool MessageCenterViewTest::HasClickedListener(
@@ -214,36 +207,14 @@ void MessageCenterViewTest::ClickOnNotificationButton(
NOTREACHED();
}
-void MessageCenterViewTest::ExpandNotification(
- const std::string& notification_id) {
- // For this test, this method should not be invoked.
- NOTREACHED();
-}
-
-void MessageCenterViewTest::GroupBodyClicked(
- const std::string& last_notification_id) {
- // For this test, this method should not be invoked.
- NOTREACHED();
-}
-
-void MessageCenterViewTest::ExpandGroup(const NotifierId& notifier_id) {
- // For this test, this method should not be invoked.
- NOTREACHED();
-}
-
-void MessageCenterViewTest::RemoveGroup(const NotifierId& notifier_id) {
- // For this test, this method should not be invoked.
- NOTREACHED();
-}
-
void MessageCenterViewTest::RegisterCall(CallType type) {
callCounts_[type] += 1;
}
void MessageCenterViewTest::LogBounds(int depth, views::View* view) {
- string16 inset;
+ base::string16 inset;
for (int i = 0; i < depth; ++i)
- inset.append(UTF8ToUTF16(" "));
+ inset.append(base::UTF8ToUTF16(" "));
gfx::Rect bounds = view->bounds();
DVLOG(0) << inset << bounds.width() << " x " << bounds.height()
<< " @ " << bounds.x() << ", " << bounds.y();
diff --git a/chromium/ui/message_center/views/message_popup_collection.cc b/chromium/ui/message_center/views/message_popup_collection.cc
index cc8c79b4656..d1116d6f346 100644
--- a/chromium/ui/message_center/views/message_popup_collection.cc
+++ b/chromium/ui/message_center/views/message_popup_collection.cc
@@ -13,16 +13,16 @@
#include "base/run_loop.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
-#include "ui/base/accessibility/accessibility_types.h"
+#include "ui/accessibility/ax_enums.h"
#include "ui/gfx/animation/animation_delegate.h"
#include "ui/gfx/animation/slide_animation.h"
#include "ui/gfx/screen.h"
#include "ui/message_center/message_center.h"
#include "ui/message_center/message_center_style.h"
#include "ui/message_center/message_center_tray.h"
-#include "ui/message_center/message_center_util.h"
#include "ui/message_center/notification.h"
#include "ui/message_center/notification_list.h"
+#include "ui/message_center/views/message_view_context_menu_controller.h"
#include "ui/message_center/views/notification_view.h"
#include "ui/message_center/views/toast_contents_view.h"
#include "ui/views/background.h"
@@ -64,42 +64,24 @@ MessagePopupCollection::MessagePopupCollection(gfx::NativeView parent,
: parent_(parent),
message_center_(message_center),
tray_(tray),
+ display_id_(gfx::Display::kInvalidDisplayID),
+ screen_(NULL),
defer_counter_(0),
latest_toast_entered_(NULL),
user_is_closing_toasts_by_clicking_(false),
first_item_has_no_margin_(first_item_has_no_margin),
+ context_menu_controller_(new MessageViewContextMenuController(this)),
weak_factory_(this) {
DCHECK(message_center_);
defer_timer_.reset(new base::OneShotTimer<MessagePopupCollection>);
message_center_->AddObserver(this);
- gfx::Screen* screen = NULL;
- gfx::Display display;
- if (!parent_) {
- // On Win+Aura, we don't have a parent since the popups currently show up
- // on the Windows desktop, not in the Aura/Ash desktop. This code will
- // display the popups on the primary display.
- screen = gfx::Screen::GetNativeScreen();
- display = screen->GetPrimaryDisplay();
- } else {
- screen = gfx::Screen::GetScreenFor(parent_);
- display = screen->GetDisplayNearestWindow(parent_);
- }
- screen->AddObserver(this);
-
- display_id_ = display.id();
- work_area_ = display.work_area();
- ComputePopupAlignment(work_area_, display.bounds());
-
- // We should not update before work area and popup alignment are computed.
- DoUpdateIfPossible();
}
MessagePopupCollection::~MessagePopupCollection() {
weak_factory_.InvalidateWeakPtrs();
- gfx::Screen* screen = parent_ ?
- gfx::Screen::GetScreenFor(parent_) : gfx::Screen::GetNativeScreen();
- screen->RemoveObserver(this);
+ if (screen_)
+ screen_->RemoveObserver(this);
message_center_->RemoveObserver(this);
CloseAllWidgets();
@@ -116,13 +98,10 @@ void MessagePopupCollection::RemoveNotification(
message_center_->RemoveNotification(notification_id, by_user);
}
-void MessagePopupCollection::DisableNotificationsFromThisSource(
- const NotifierId& notifier_id) {
- message_center_->DisableNotificationsByNotifier(notifier_id);
-}
-
-void MessagePopupCollection::ShowNotifierSettingsBubble() {
- tray_->ShowNotifierSettingsBubble();
+scoped_ptr<ui::MenuModel> MessagePopupCollection::CreateMenuModel(
+ const NotifierId& notifier_id,
+ const base::string16& display_source) {
+ return tray_->CreateNotificationMenuModel(notifier_id, display_source);
}
bool MessagePopupCollection::HasClickedListener(
@@ -136,29 +115,6 @@ void MessagePopupCollection::ClickOnNotificationButton(
message_center_->ClickOnNotificationButton(notification_id, button_index);
}
-void MessagePopupCollection::ExpandNotification(
- const std::string& notification_id) {
- message_center_->ExpandNotification(notification_id);
-}
-
-void MessagePopupCollection::GroupBodyClicked(
- const std::string& last_notification_id) {
- // No group views in popup collection.
- NOTREACHED();
-}
-
-// When clicked on the "N more" button, perform some reasonable action.
-// TODO(dimich): find out what the reasonable action could be.
-void MessagePopupCollection::ExpandGroup(const NotifierId& notifier_id) {
- // No group views in popup collection.
- NOTREACHED();
-}
-
-void MessagePopupCollection::RemoveGroup(const NotifierId& notifier_id) {
- // No group views in popup collection.
- NOTREACHED();
-}
-
void MessagePopupCollection::MarkAllPopupsShown() {
std::set<std::string> closed_ids = CloseAllWidgets();
for (std::set<std::string>::iterator iter = closed_ids.begin();
@@ -186,14 +142,11 @@ void MessagePopupCollection::UpdateWidgets() {
if (FindToast((*iter)->id()))
continue;
- bool expanded = true;
- if (IsExperimentalNotificationUIEnabled())
- expanded = (*iter)->is_expanded();
NotificationView* view =
NotificationView::Create(NULL,
*(*iter),
- expanded,
true); // Create top-level notification.
+ view->set_context_menu_controller(context_menu_controller_.get());
int view_height = ToastContentsView::GetToastSizeForView(view).height();
int height_available = top_down ? work_area_.bottom() - base : base;
@@ -230,10 +183,11 @@ void MessagePopupCollection::UpdateWidgets() {
if (views::ViewsDelegate::views_delegate) {
views::ViewsDelegate::views_delegate->NotifyAccessibilityEvent(
- toast, ui::AccessibilityTypes::EVENT_ALERT);
+ toast, ui::AX_EVENT_ALERT);
}
- message_center_->DisplayedNotification((*iter)->id());
+ message_center_->DisplayedNotification(
+ (*iter)->id(), message_center::DISPLAY_SOURCE_POPUP);
}
}
@@ -496,24 +450,22 @@ void MessagePopupCollection::OnNotificationUpdated(
for (NotificationList::PopupNotifications::iterator iter =
notifications.begin(); iter != notifications.end(); ++iter) {
- if ((*iter)->id() != notification_id)
- continue;
+ Notification* notification = *iter;
+ DCHECK(notification);
+ ToastContentsView* toast_contents_view = *toast_iter;
+ DCHECK(toast_contents_view);
- bool expanded = true;
- if (IsExperimentalNotificationUIEnabled())
- expanded = (*iter)->is_expanded();
+ if (notification->id() != notification_id)
+ continue;
const RichNotificationData& optional_fields =
- (*iter)->rich_notification_data();
+ notification->rich_notification_data();
bool a11y_feedback_for_updates =
optional_fields.should_make_spoken_feedback_for_popup_updates;
- NotificationView* view =
- NotificationView::Create(*toast_iter,
- *(*iter),
- expanded,
- true); // Create top-level notification.
- (*toast_iter)->SetContents(view, a11y_feedback_for_updates);
+ toast_contents_view->UpdateContents(*notification,
+ a11y_feedback_for_updates);
+
updated = true;
}
@@ -556,6 +508,28 @@ void MessagePopupCollection::DecrementDeferCounter() {
// deferred tasks are even able to run)
// Then, see if there is vacant space for new toasts.
void MessagePopupCollection::DoUpdateIfPossible() {
+ if (!screen_) {
+ gfx::Display display;
+ if (!parent_) {
+ // On Win+Aura, we don't have a parent since the popups currently show up
+ // on the Windows desktop, not in the Aura/Ash desktop. This code will
+ // display the popups on the primary display.
+ screen_ = gfx::Screen::GetNativeScreen();
+ display = screen_->GetPrimaryDisplay();
+ } else {
+ screen_ = gfx::Screen::GetScreenFor(parent_);
+ display = screen_->GetDisplayNearestWindow(parent_);
+ }
+ screen_->AddObserver(this);
+
+ display_id_ = display.id();
+ // |work_area_| can be set already and it should not be overwritten here.
+ if (work_area_.IsEmpty()) {
+ work_area_ = display.work_area();
+ ComputePopupAlignment(work_area_, display.bounds());
+ }
+ }
+
if (defer_counter_ > 0)
return;
@@ -587,18 +561,24 @@ void MessagePopupCollection::SetDisplayInfo(const gfx::Rect& work_area,
RepositionWidgets();
}
-void MessagePopupCollection::OnDisplayBoundsChanged(
- const gfx::Display& display) {
- if (display.id() != display_id_)
- return;
-
- SetDisplayInfo(display.work_area(), display.bounds());
-}
-
void MessagePopupCollection::OnDisplayAdded(const gfx::Display& new_display) {
}
void MessagePopupCollection::OnDisplayRemoved(const gfx::Display& old_display) {
+ if (display_id_ == old_display.id() && !parent_) {
+ gfx::Display display = gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
+ display_id_ = display.id();
+ SetDisplayInfo(display.work_area(), display.bounds());
+ }
+}
+
+void MessagePopupCollection::OnDisplayMetricsChanged(
+ const gfx::Display& display, uint32_t metrics) {
+ if (display.id() != display_id_)
+ return;
+
+ if (metrics & DISPLAY_METRIC_BOUNDS || metrics & DISPLAY_METRIC_WORK_AREA)
+ SetDisplayInfo(display.work_area(), display.bounds());
}
views::Widget* MessagePopupCollection::GetWidgetForTest(const std::string& id)
diff --git a/chromium/ui/message_center/views/message_popup_collection.h b/chromium/ui/message_center/views/message_popup_collection.h
index 48345d80d75..955af32ddb5 100644
--- a/chromium/ui/message_center/views/message_popup_collection.h
+++ b/chromium/ui/message_center/views/message_popup_collection.h
@@ -35,6 +35,10 @@ class WebNotificationTrayTest;
FORWARD_DECLARE_TEST(WebNotificationTrayTest, ManyPopupNotifications);
}
+namespace gfx {
+class Screen;
+}
+
namespace message_center {
namespace test {
class MessagePopupCollectionTest;
@@ -42,6 +46,7 @@ class MessagePopupCollectionTest;
class MessageCenter;
class MessageCenterTray;
+class MessageViewContextMenuController;
enum PopupAlignment {
POPUP_ALIGNMENT_TOP = 1 << 0,
@@ -74,17 +79,12 @@ class MESSAGE_CENTER_EXPORT MessagePopupCollection
virtual void ClickOnNotification(const std::string& notification_id) OVERRIDE;
virtual void RemoveNotification(const std::string& notification_id,
bool by_user) OVERRIDE;
- virtual void DisableNotificationsFromThisSource(
- const NotifierId& notifier_id) OVERRIDE;
- virtual void ShowNotifierSettingsBubble() OVERRIDE;
+ virtual scoped_ptr<ui::MenuModel> CreateMenuModel(
+ const NotifierId& notifier_id,
+ const base::string16& display_source) OVERRIDE;
virtual bool HasClickedListener(const std::string& notification_id) OVERRIDE;
virtual void ClickOnNotificationButton(const std::string& notification_id,
int button_index) OVERRIDE;
- virtual void ExpandNotification(const std::string& notification_id) OVERRIDE;
- virtual void GroupBodyClicked(const std::string& last_notification_id)
- OVERRIDE;
- virtual void ExpandGroup(const NotifierId& notifier_id) OVERRIDE;
- virtual void RemoveGroup(const NotifierId& notifier_id) OVERRIDE;
void MarkAllPopupsShown();
@@ -111,7 +111,7 @@ class MESSAGE_CENTER_EXPORT MessagePopupCollection
// Updates |work_area_| and re-calculates the alignment of notification toasts
// rearranging them if necessary.
- // This is separated from methods from OnDisplayBoundsChanged(), since
+ // This is separated from methods from OnDisplayMetricsChanged(), since
// sometimes the display info has to be specified directly. One example is
// shelf's auto-hide change. When the shelf in ChromeOS is temporarily shown
// from auto hide status, it doesn't change the display's work area but the
@@ -120,9 +120,10 @@ class MESSAGE_CENTER_EXPORT MessagePopupCollection
const gfx::Rect& screen_bounds);
// Overridden from gfx::DislayObserver:
- virtual void OnDisplayBoundsChanged(const gfx::Display& display) OVERRIDE;
virtual void OnDisplayAdded(const gfx::Display& new_display) OVERRIDE;
virtual void OnDisplayRemoved(const gfx::Display& old_display) OVERRIDE;
+ virtual void OnDisplayMetricsChanged(const gfx::Display& display,
+ uint32_t metrics) OVERRIDE;
// Used by ToastContentsView to locate itself.
gfx::NativeView parent() const { return parent_; }
@@ -188,6 +189,7 @@ class MESSAGE_CENTER_EXPORT MessagePopupCollection
Toasts toasts_;
gfx::Rect work_area_;
int64 display_id_;
+ gfx::Screen* screen_;
// Specifies which corner of the screen popups should show up. This should
// ideally be the same corner the notification area (systray) is at.
@@ -216,6 +218,8 @@ class MESSAGE_CENTER_EXPORT MessagePopupCollection
// True if the first item should not have spacing against the tray.
bool first_item_has_no_margin_;
+ scoped_ptr<MessageViewContextMenuController> context_menu_controller_;
+
// Gives out weak pointers to toast contents views which have an unrelated
// lifetime. Must remain the last member variable.
base::WeakPtrFactory<MessagePopupCollection> weak_factory_;
diff --git a/chromium/ui/message_center/views/message_popup_collection_unittest.cc b/chromium/ui/message_center/views/message_popup_collection_unittest.cc
index f763b516743..eacc6807726 100644
--- a/chromium/ui/message_center/views/message_popup_collection_unittest.cc
+++ b/chromium/ui/message_center/views/message_popup_collection_unittest.cc
@@ -87,10 +87,10 @@ class MessagePopupCollectionTest : public views::ViewsTestBase {
scoped_ptr<Notification> notification(
new Notification(NOTIFICATION_TYPE_BASE_FORMAT,
id,
- UTF8ToUTF16("test title"),
- UTF8ToUTF16("test message"),
+ base::UTF8ToUTF16("test title"),
+ base::UTF8ToUTF16("test message"),
gfx::Image(),
- string16() /* display_source */,
+ base::string16() /* display_source */,
NotifierId(),
message_center::RichNotificationData(),
NULL /* delegate */));
@@ -358,7 +358,7 @@ TEST_F(MessagePopupCollectionTest, DetectMouseHover) {
views::WidgetDelegateView* toast1 = GetToast(id1);
EXPECT_TRUE(toast1 != NULL);
- ui::MouseEvent event(ui::ET_MOUSE_MOVED, gfx::Point(), gfx::Point(), 0);
+ ui::MouseEvent event(ui::ET_MOUSE_MOVED, gfx::Point(), gfx::Point(), 0, 0);
// Test that mouse detection logic works in presence of out-of-order events.
toast0->OnMouseEntered(event);
@@ -393,7 +393,7 @@ TEST_F(MessagePopupCollectionTest, DetectMouseHoverWithUserClose) {
views::WidgetDelegateView* toast1 = GetToast(id1);
ASSERT_TRUE(toast1 != NULL);
- ui::MouseEvent event(ui::ET_MOUSE_MOVED, gfx::Point(), gfx::Point(), 0);
+ ui::MouseEvent event(ui::ET_MOUSE_MOVED, gfx::Point(), gfx::Point(), 0, 0);
toast1->OnMouseEntered(event);
static_cast<MessageCenterObserver*>(collection())->OnNotificationRemoved(
id1, true);
diff --git a/chromium/ui/message_center/views/message_view.cc b/chromium/ui/message_center/views/message_view.cc
index ccf1074b2e6..11ff5485f86 100644
--- a/chromium/ui/message_center/views/message_view.cc
+++ b/chromium/ui/message_center/views/message_view.cc
@@ -6,7 +6,7 @@
#include "grit/ui_resources.h"
#include "grit/ui_strings.h"
-#include "ui/base/accessibility/accessible_view_state.h"
+#include "ui/accessibility/ax_view_state.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/models/simple_menu_model.h"
#include "ui/base/resource/resource_bundle.h"
@@ -14,15 +14,14 @@
#include "ui/gfx/canvas.h"
#include "ui/message_center/message_center.h"
#include "ui/message_center/message_center_style.h"
-#include "ui/message_center/message_center_util.h"
#include "ui/message_center/views/padded_button.h"
-#include "ui/views/context_menu_controller.h"
+#include "ui/views/background.h"
#include "ui/views/controls/button/image_button.h"
-#include "ui/views/controls/menu/menu_runner.h"
+#include "ui/views/controls/image_view.h"
#include "ui/views/controls/scroll_view.h"
+#include "ui/views/focus/focus_manager.h"
#include "ui/views/painter.h"
#include "ui/views/shadow_border.h"
-#include "ui/views/widget/widget.h"
namespace {
@@ -32,161 +31,48 @@ const int kCloseIconRightPadding = 5;
const int kShadowOffset = 1;
const int kShadowBlur = 4;
-// Menu constants
-const int kTogglePermissionCommand = 0;
-const int kShowSettingsCommand = 1;
-
-// A dropdown menu for notifications.
-class MenuModel : public ui::SimpleMenuModel,
- public ui::SimpleMenuModel::Delegate {
- public:
- MenuModel(message_center::MessageViewController* controller,
- message_center::NotifierId notifier_id,
- const string16& display_source);
- virtual ~MenuModel();
-
- // Overridden from ui::SimpleMenuModel::Delegate:
- virtual bool IsItemForCommandIdDynamic(int command_id) const OVERRIDE;
- virtual bool IsCommandIdChecked(int command_id) const OVERRIDE;
- virtual bool IsCommandIdEnabled(int command_id) const OVERRIDE;
- virtual bool GetAcceleratorForCommandId(
- int command_id,
- ui::Accelerator* accelerator) OVERRIDE;
- virtual void ExecuteCommand(int command_id, int event_flags) OVERRIDE;
-
- private:
- message_center::MessageViewController* controller_;
- message_center::NotifierId notifier_id_;
- DISALLOW_COPY_AND_ASSIGN(MenuModel);
-};
-
-MenuModel::MenuModel(message_center::MessageViewController* controller,
- message_center::NotifierId notifier_id,
- const string16& display_source)
- : ui::SimpleMenuModel(this),
- controller_(controller),
- notifier_id_(notifier_id) {
- // Add 'disable notifications' menu item.
- if (!display_source.empty()) {
- AddItem(kTogglePermissionCommand,
- l10n_util::GetStringFUTF16(IDS_MESSAGE_CENTER_NOTIFIER_DISABLE,
- display_source));
- }
- // Add settings menu item.
- AddItem(kShowSettingsCommand,
- l10n_util::GetStringUTF16(IDS_MESSAGE_CENTER_SETTINGS));
-}
-
-MenuModel::~MenuModel() {
-}
-
-bool MenuModel::IsItemForCommandIdDynamic(int command_id) const {
- return false;
-}
-
-bool MenuModel::IsCommandIdChecked(int command_id) const {
- return false;
-}
-
-bool MenuModel::IsCommandIdEnabled(int command_id) const {
- return true;
-}
-
-bool MenuModel::GetAcceleratorForCommandId(int command_id,
- ui::Accelerator* accelerator) {
- return false;
-}
-
-void MenuModel::ExecuteCommand(int command_id, int event_flags) {
- switch (command_id) {
- case kTogglePermissionCommand:
- controller_->DisableNotificationsFromThisSource(notifier_id_);
- break;
- case kShowSettingsCommand:
- controller_->ShowNotifierSettingsBubble();
- break;
- default:
- NOTREACHED();
- }
-}
-
} // namespace
namespace message_center {
-class MessageViewContextMenuController : public views::ContextMenuController {
- public:
- MessageViewContextMenuController(MessageViewController* controller,
- const NotifierId& notifier_id,
- const string16& display_source);
- virtual ~MessageViewContextMenuController();
-
- protected:
- // Overridden from views::ContextMenuController:
- virtual void ShowContextMenuForView(views::View* source,
- const gfx::Point& point,
- ui::MenuSourceType source_type) OVERRIDE;
-
- MessageViewController* controller_; // Weak, owns us.
- NotifierId notifier_id_;
- string16 display_source_;
-};
-
-MessageViewContextMenuController::MessageViewContextMenuController(
- MessageViewController* controller,
- const NotifierId& notifier_id,
- const string16& display_source)
- : controller_(controller),
- notifier_id_(notifier_id),
- display_source_(display_source) {
-}
-
-MessageViewContextMenuController::~MessageViewContextMenuController() {
-}
-
-void MessageViewContextMenuController::ShowContextMenuForView(
- views::View* source,
- const gfx::Point& point,
- ui::MenuSourceType source_type) {
- MenuModel menu_model(controller_, notifier_id_, display_source_);
- if (menu_model.GetItemCount() == 0)
- return;
-
- views::MenuRunner menu_runner(&menu_model);
-
- ignore_result(menu_runner.RunMenuAt(
- source->GetWidget()->GetTopLevelWidget(),
- NULL,
- gfx::Rect(point, gfx::Size()),
- views::MenuItemView::TOPRIGHT,
- source_type,
- views::MenuRunner::HAS_MNEMONICS));
-}
-
MessageView::MessageView(MessageViewController* controller,
const std::string& notification_id,
const NotifierId& notifier_id,
- const string16& display_source)
+ const gfx::ImageSkia& small_image,
+ const base::string16& display_source)
: controller_(controller),
notification_id_(notification_id),
notifier_id_(notifier_id),
- context_menu_controller_(
- new MessageViewContextMenuController(controller,
- notifier_id,
- display_source)),
- scroller_(NULL) {
+ background_view_(NULL),
+ scroller_(NULL),
+ display_source_(display_source) {
SetFocusable(true);
- set_context_menu_controller(context_menu_controller_.get());
+
+ // Create the opaque background that's above the view's shadow.
+ background_view_ = new views::View();
+ background_view_->set_background(
+ views::Background::CreateSolidBackground(kNotificationBackgroundColor));
+ AddChildView(background_view_);
+
+ views::ImageView* small_image_view = new views::ImageView();
+ small_image_view->SetImage(small_image);
+ small_image_view->SetImageSize(gfx::Size(kSmallImageSize, kSmallImageSize));
+ // The small image view should be added to view hierarchy by the derived
+ // class. This ensures that it is on top of other views.
+ small_image_view->set_owned_by_client();
+ small_image_view_.reset(small_image_view);
PaddedButton *close = new PaddedButton(this);
close->SetPadding(-kCloseIconRightPadding, kCloseIconTopPadding);
close->SetNormalImage(IDR_NOTIFICATION_CLOSE);
close->SetHoveredImage(IDR_NOTIFICATION_CLOSE_HOVER);
close->SetPressedImage(IDR_NOTIFICATION_CLOSE_PRESSED);
- close->set_owned_by_client();
close->set_animate_on_state_change(false);
close->SetAccessibleName(l10n_util::GetStringUTF16(
IDS_MESSAGE_CENTER_CLOSE_NOTIFICATION_BUTTON_ACCESSIBLE_NAME));
+ // The close button should be added to view hierarchy by the derived class.
+ // This ensures that it is on top of other views.
+ close->set_owned_by_client();
close_button_.reset(close);
focus_painter_ = views::Painter::CreateSolidFocusPainter(
@@ -197,6 +83,11 @@ MessageView::MessageView(MessageViewController* controller,
MessageView::~MessageView() {
}
+void MessageView::UpdateWithNotification(const Notification& notification) {
+ small_image_view_->SetImage(notification.small_image().AsImageSkia());
+ display_source_ = notification.display_source();
+}
+
// static
gfx::Insets MessageView::GetShadowInsets() {
return gfx::Insets(kShadowBlur / 2 - kShadowOffset,
@@ -206,10 +97,11 @@ gfx::Insets MessageView::GetShadowInsets() {
}
void MessageView::CreateShadowBorder() {
- set_border(new views::ShadowBorder(kShadowBlur,
- message_center::kShadowColor,
- kShadowOffset, // Vertical offset.
- 0)); // Horizontal offset.
+ SetBorder(scoped_ptr<views::Border>(
+ new views::ShadowBorder(kShadowBlur,
+ message_center::kShadowColor,
+ kShadowOffset, // Vertical offset.
+ 0))); // Horizontal offset.
}
bool MessageView::IsCloseButtonFocused() {
@@ -221,8 +113,8 @@ void MessageView::RequestFocusOnCloseButton() {
close_button_->RequestFocus();
}
-void MessageView::GetAccessibleState(ui::AccessibleViewState* state) {
- state->role = ui::AccessibilityTypes::ROLE_PUSHBUTTON;
+void MessageView::GetAccessibleState(ui::AXViewState* state) {
+ state->role = ui::AX_ROLE_BUTTON;
state->name = accessible_name_;
}
@@ -261,6 +153,8 @@ bool MessageView::OnKeyReleased(const ui::KeyEvent& event) {
}
void MessageView::OnPaint(gfx::Canvas* canvas) {
+ DCHECK_EQ(this, close_button_->parent());
+ DCHECK_EQ(this, small_image_view_->parent());
SlideOutView::OnPaint(canvas);
views::Painter::PaintFocusPainter(this, canvas, focus_painter_.get());
}
@@ -277,6 +171,29 @@ void MessageView::OnBlur() {
SchedulePaint();
}
+void MessageView::Layout() {
+ gfx::Rect content_bounds = GetContentsBounds();
+
+ // Background.
+ background_view_->SetBoundsRect(content_bounds);
+
+ // Close button.
+ gfx::Size close_size(close_button_->GetPreferredSize());
+ gfx::Rect close_rect(content_bounds.right() - close_size.width(),
+ content_bounds.y(),
+ close_size.width(),
+ close_size.height());
+ close_button_->SetBoundsRect(close_rect);
+
+ gfx::Size small_image_size(small_image_view_->GetPreferredSize());
+ gfx::Rect small_image_rect(small_image_size);
+ small_image_rect.set_origin(gfx::Point(
+ content_bounds.right() - small_image_size.width() - kSmallImagePadding,
+ content_bounds.bottom() - small_image_size.height() -
+ kSmallImagePadding));
+ small_image_view_->SetBoundsRect(small_image_rect);
+}
+
void MessageView::OnGestureEvent(ui::GestureEvent* event) {
if (event->type() == ui::ET_GESTURE_TAP) {
controller_->ClickOnNotification(notification_id_);
diff --git a/chromium/ui/message_center/views/message_view.h b/chromium/ui/message_center/views/message_view.h
index ba42e3fc73c..04f4d97a06b 100644
--- a/chromium/ui/message_center/views/message_view.h
+++ b/chromium/ui/message_center/views/message_view.h
@@ -13,8 +13,13 @@
#include "ui/views/controls/button/button.h"
#include "ui/views/controls/slide_out_view.h"
+namespace ui {
+class MenuModel;
+}
+
namespace views {
class ImageButton;
+class ImageView;
class Painter;
class ScrollView;
}
@@ -28,29 +33,29 @@ class MessageViewController {
virtual void ClickOnNotification(const std::string& notification_id) = 0;
virtual void RemoveNotification(const std::string& notification_id,
bool by_user) = 0;
- virtual void DisableNotificationsFromThisSource(
- const NotifierId& notifier_id) = 0;
- virtual void ShowNotifierSettingsBubble() = 0;
};
-class MessageViewContextMenuController;
-
// Individual notifications constants.
const int kPaddingBetweenItems = 10;
const int kPaddingHorizontal = 18;
const int kWebNotificationButtonWidth = 32;
const int kWebNotificationIconSize = 40;
-// An abstract class that forms the basis of a view for a notification entry.
+// An base class for a notification entry. Contains background, close button
+// and other elements shared by derived notification views.
class MESSAGE_CENTER_EXPORT MessageView : public views::SlideOutView,
public views::ButtonListener {
public:
MessageView(MessageViewController* controller,
const std::string& notification_id,
const NotifierId& notifier_id,
- const string16& display_source);
+ const gfx::ImageSkia& small_image,
+ const base::string16& display_source);
virtual ~MessageView();
+ // Updates this view with the new data contained in the notification.
+ virtual void UpdateWithNotification(const Notification& notification);
+
// Returns the insets for the shadow it will have for rich notification.
static gfx::Insets GetShadowInsets();
@@ -60,16 +65,19 @@ class MESSAGE_CENTER_EXPORT MessageView : public views::SlideOutView,
bool IsCloseButtonFocused();
void RequestFocusOnCloseButton();
- void set_accessible_name(const string16& name) { accessible_name_ = name; }
+ void set_accessible_name(const base::string16& accessible_name) {
+ accessible_name_ = accessible_name;
+ }
// Overridden from views::View:
- virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE;
+ virtual void GetAccessibleState(ui::AXViewState* state) OVERRIDE;
virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE;
virtual bool OnKeyPressed(const ui::KeyEvent& event) OVERRIDE;
virtual bool OnKeyReleased(const ui::KeyEvent& event) OVERRIDE;
virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE;
virtual void OnFocus() OVERRIDE;
virtual void OnBlur() OVERRIDE;
+ virtual void Layout() OVERRIDE;
// Overridden from ui::EventHandler:
virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE;
@@ -81,11 +89,13 @@ class MESSAGE_CENTER_EXPORT MessageView : public views::SlideOutView,
void set_scroller(views::ScrollView* scroller) { scroller_ = scroller; }
std::string notification_id() { return notification_id_; }
NotifierId notifier_id() { return notifier_id_; }
+ const base::string16& display_source() const { return display_source_; }
protected:
// Overridden from views::SlideOutView:
virtual void OnSlideOut() OVERRIDE;
+ views::ImageView* small_image() { return small_image_view_.get(); }
views::ImageButton* close_button() { return close_button_.get(); }
views::ScrollView* scroller() { return scroller_; }
@@ -93,11 +103,14 @@ class MESSAGE_CENTER_EXPORT MessageView : public views::SlideOutView,
MessageViewController* controller_;
std::string notification_id_;
NotifierId notifier_id_;
- scoped_ptr<MessageViewContextMenuController> context_menu_controller_;
+ views::View* background_view_; // Owned by views hierarchy.
scoped_ptr<views::ImageButton> close_button_;
+ scoped_ptr<views::ImageView> small_image_view_;
views::ScrollView* scroller_;
- string16 accessible_name_;
+ base::string16 accessible_name_;
+
+ base::string16 display_source_;
scoped_ptr<views::Painter> focus_painter_;
diff --git a/chromium/ui/message_center/views/message_view_context_menu_controller.cc b/chromium/ui/message_center/views/message_view_context_menu_controller.cc
new file mode 100644
index 00000000000..3edaa29faa7
--- /dev/null
+++ b/chromium/ui/message_center/views/message_view_context_menu_controller.cc
@@ -0,0 +1,45 @@
+// 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 "ui/message_center/views/message_view_context_menu_controller.h"
+
+#include "ui/base/models/menu_model.h"
+#include "ui/message_center/views/message_center_controller.h"
+#include "ui/message_center/views/message_view.h"
+#include "ui/views/controls/menu/menu_runner.h"
+#include "ui/views/widget/widget.h"
+
+namespace message_center {
+
+MessageViewContextMenuController::MessageViewContextMenuController(
+ MessageCenterController* controller)
+ : controller_(controller) {
+}
+
+MessageViewContextMenuController::~MessageViewContextMenuController() {
+}
+
+void MessageViewContextMenuController::ShowContextMenuForView(
+ views::View* source,
+ const gfx::Point& point,
+ ui::MenuSourceType source_type) {
+ // Assumes that the target view has to be MessageView.
+ MessageView* message_view = static_cast<MessageView*>(source);
+ scoped_ptr<ui::MenuModel> menu_model(controller_->CreateMenuModel(
+ message_view->notifier_id(), message_view->display_source()));
+
+ if (!menu_model || menu_model->GetItemCount() == 0)
+ return;
+
+ views::MenuRunner menu_runner(menu_model.get());
+
+ ignore_result(menu_runner.RunMenuAt(source->GetWidget()->GetTopLevelWidget(),
+ NULL,
+ gfx::Rect(point, gfx::Size()),
+ views::MENU_ANCHOR_TOPRIGHT,
+ source_type,
+ views::MenuRunner::HAS_MNEMONICS));
+}
+
+} // namespace message_center
diff --git a/chromium/ui/message_center/views/message_view_context_menu_controller.h b/chromium/ui/message_center/views/message_view_context_menu_controller.h
new file mode 100644
index 00000000000..5ee39de1a07
--- /dev/null
+++ b/chromium/ui/message_center/views/message_view_context_menu_controller.h
@@ -0,0 +1,34 @@
+// 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.
+
+#ifndef UI_MESSAGE_CENTER_VIEWS_MESSAGE_VIEW_CONTEXT_MENU_CONTROLLER_H_
+#define UI_MESSAGE_CENTER_VIEWS_MESSAGE_VIEW_CONTEXT_MENU_CONTROLLER_H_
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "ui/views/context_menu_controller.h"
+
+namespace message_center {
+class MessageCenterController;
+
+class MessageViewContextMenuController : public views::ContextMenuController {
+ public:
+ explicit MessageViewContextMenuController(
+ MessageCenterController* controller);
+ virtual ~MessageViewContextMenuController();
+
+ private:
+ // Overridden from views::ContextMenuController:
+ virtual void ShowContextMenuForView(views::View* source,
+ const gfx::Point& point,
+ ui::MenuSourceType source_type) OVERRIDE;
+
+ MessageCenterController* controller_;
+
+ DISALLOW_COPY_AND_ASSIGN(MessageViewContextMenuController);
+};
+
+} // namespace message_center
+
+#endif // UI_MESSAGE_CENTER_VIEWS_MESSAGE_VIEW_CONTEXT_MENU_CONTROLLER_H_
diff --git a/chromium/ui/message_center/views/notification_button.cc b/chromium/ui/message_center/views/notification_button.cc
index 7ef5295ad22..75219e8d3dc 100644
--- a/chromium/ui/message_center/views/notification_button.cc
+++ b/chromium/ui/message_center/views/notification_button.cc
@@ -48,13 +48,13 @@ void NotificationButton::SetIcon(const gfx::ImageSkia& image) {
icon_->SetImage(image);
icon_->SetHorizontalAlignment(views::ImageView::LEADING);
icon_->SetVerticalAlignment(views::ImageView::LEADING);
- icon_->set_border(views::Border::CreateEmptyBorder(
+ icon_->SetBorder(views::Border::CreateEmptyBorder(
message_center::kButtonIconTopPadding, 0, 0, 0));
AddChildViewAt(icon_, 0);
}
}
-void NotificationButton::SetTitle(const string16& title) {
+void NotificationButton::SetTitle(const base::string16& title) {
if (title_ != NULL)
delete title_; // This removes the title from this view's children.
if (title.empty()) {
@@ -64,19 +64,19 @@ void NotificationButton::SetTitle(const string16& title) {
title_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
title_->SetEnabledColor(message_center::kRegularTextColor);
title_->SetBackgroundColor(kRegularTextBackgroundColor);
- title_->set_border(views::Border::CreateEmptyBorder(
- kButtonTitleTopPadding, 0, 0, 0));
+ title_->SetBorder(
+ views::Border::CreateEmptyBorder(kButtonTitleTopPadding, 0, 0, 0));
AddChildView(title_);
}
SetAccessibleName(title);
}
-gfx::Size NotificationButton::GetPreferredSize() {
+gfx::Size NotificationButton::GetPreferredSize() const {
return gfx::Size(message_center::kNotificationWidth,
message_center::kButtonHeight);
}
-int NotificationButton::GetHeightForWidth(int width) {
+int NotificationButton::GetHeightForWidth(int width) const {
return message_center::kButtonHeight;
}
@@ -98,6 +98,14 @@ void NotificationButton::OnBlur() {
SchedulePaint();
}
+void NotificationButton::ViewHierarchyChanged(
+ const ViewHierarchyChangedDetails& details) {
+ // We disable view hierarchy change detection in the parent
+ // because it resets the hoverstate, which we do not want
+ // when we update the view to contain a new label or image.
+ views::View::ViewHierarchyChanged(details);
+}
+
void NotificationButton::StateChanged() {
if (state() == STATE_HOVERED || state() == STATE_PRESSED) {
set_background(views::Background::CreateSolidBackground(
diff --git a/chromium/ui/message_center/views/notification_button.h b/chromium/ui/message_center/views/notification_button.h
index 7d3c52ce1ea..b5ac0f12981 100644
--- a/chromium/ui/message_center/views/notification_button.h
+++ b/chromium/ui/message_center/views/notification_button.h
@@ -24,14 +24,16 @@ class NotificationButton : public views::CustomButton {
virtual ~NotificationButton();
void SetIcon(const gfx::ImageSkia& icon);
- void SetTitle(const string16& title);
+ void SetTitle(const base::string16& title);
// Overridden from views::View:
- virtual gfx::Size GetPreferredSize() OVERRIDE;
- virtual int GetHeightForWidth(int width) OVERRIDE;
+ virtual gfx::Size GetPreferredSize() const OVERRIDE;
+ virtual int GetHeightForWidth(int width) const OVERRIDE;
virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE;
virtual void OnFocus() OVERRIDE;
virtual void OnBlur() OVERRIDE;
+ virtual void ViewHierarchyChanged(
+ const ViewHierarchyChangedDetails& details) OVERRIDE;
// Overridden from views::CustomButton:
virtual void StateChanged() OVERRIDE;
diff --git a/chromium/ui/message_center/views/notification_view.cc b/chromium/ui/message_center/views/notification_view.cc
index 4a5d67326be..be77657f6e0 100644
--- a/chromium/ui/message_center/views/notification_view.cc
+++ b/chromium/ui/message_center/views/notification_view.cc
@@ -5,10 +5,12 @@
#include "ui/message_center/views/notification_view.h"
#include "base/command_line.h"
+#include "base/stl_util.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "grit/ui_resources.h"
#include "grit/ui_strings.h"
+#include "ui/base/cursor/cursor.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/layout.h"
#include "ui/base/resource/resource_bundle.h"
@@ -18,8 +20,6 @@
#include "ui/gfx/text_elider.h"
#include "ui/message_center/message_center.h"
#include "ui/message_center/message_center_style.h"
-#include "ui/message_center/message_center_switches.h"
-#include "ui/message_center/message_center_util.h"
#include "ui/message_center/notification.h"
#include "ui/message_center/notification_types.h"
#include "ui/message_center/views/bounded_label.h"
@@ -37,35 +37,27 @@
#include "ui/views/controls/progress_bar.h"
#include "ui/views/layout/box_layout.h"
#include "ui/views/layout/fill_layout.h"
+#include "ui/views/native_cursor.h"
#include "ui/views/painter.h"
#include "ui/views/widget/widget.h"
-#if defined(USE_AURA)
-#include "ui/base/cursor/cursor.h"
-#endif
-
namespace {
// Dimensions.
const int kProgressBarWidth = message_center::kNotificationWidth -
message_center::kTextLeftPadding - message_center::kTextRightPadding;
const int kProgressBarBottomPadding = 0;
-const int kExpandIconBottomPadding = 8;
-const int kExpandIconRightPadding = 11;
-
-// static
-views::Background* MakeBackground(
- SkColor color = message_center::kNotificationBackgroundColor) {
- return views::Background::CreateSolidBackground(color);
-}
// static
-views::Border* MakeEmptyBorder(int top, int left, int bottom, int right) {
+scoped_ptr<views::Border> MakeEmptyBorder(int top,
+ int left,
+ int bottom,
+ int right) {
return views::Border::CreateEmptyBorder(top, left, bottom, right);
}
// static
-views::Border* MakeTextBorder(int padding, int top, int bottom) {
+scoped_ptr<views::Border> MakeTextBorder(int padding, int top, int bottom) {
// Split the padding between the top and the bottom, then add the extra space.
return MakeEmptyBorder(padding / 2 + top,
message_center::kTextLeftPadding,
@@ -74,7 +66,7 @@ views::Border* MakeTextBorder(int padding, int top, int bottom) {
}
// static
-views::Border* MakeProgressBarBorder(int top, int bottom) {
+scoped_ptr<views::Border> MakeProgressBarBorder(int top, int bottom) {
return MakeEmptyBorder(top,
message_center::kTextLeftPadding,
bottom,
@@ -82,7 +74,9 @@ views::Border* MakeProgressBarBorder(int top, int bottom) {
}
// static
-views::Border* MakeSeparatorBorder(int top, int left, SkColor color) {
+scoped_ptr<views::Border> MakeSeparatorBorder(int top,
+ int left,
+ SkColor color) {
return views::Border::CreateSolidSidedBorder(top, left, 0, 0, color);
}
@@ -90,16 +84,12 @@ views::Border* MakeSeparatorBorder(int top, int left, SkColor color) {
// Return true if and only if the image is null or has alpha.
bool HasAlpha(gfx::ImageSkia& image, views::Widget* widget) {
// Determine which bitmap to use.
- ui::ScaleFactor factor = ui::SCALE_FACTOR_100P;
- if (widget) {
+ float factor = 1.0f;
+ if (widget)
factor = ui::GetScaleFactorForNativeView(widget->GetNativeView());
- if (factor == ui::SCALE_FACTOR_NONE)
- factor = ui::SCALE_FACTOR_100P;
- }
// Extract that bitmap's alpha and look for a non-opaque pixel there.
- SkBitmap bitmap =
- image.GetRepresentation(ui::GetImageScale(factor)).sk_bitmap();
+ SkBitmap bitmap = image.GetRepresentation(factor).sk_bitmap();
if (!bitmap.isNull()) {
SkBitmap alpha;
bitmap.extractAlpha(&alpha);
@@ -175,19 +165,20 @@ views::View* MakeNotificationImage(const gfx::Image& image, gfx::Size size) {
container->set_background(views::Background::CreateSolidBackground(
message_center::kImageBackgroundColor));
- views::View* proportional_image_view =
- new message_center::ProportionalImageView(image.AsImageSkia());
-
gfx::Size ideal_size(
message_center::kNotificationPreferredImageWidth,
message_center::kNotificationPreferredImageHeight);
- gfx::Size scaled_size = message_center::GetImageSizeForWidth(
- message_center::kNotificationPreferredImageWidth, image.Size());
+ gfx::Size scaled_size =
+ message_center::GetImageSizeForContainerSize(ideal_size, image.Size());
+
+ views::View* proportional_image_view =
+ new message_center::ProportionalImageView(image.AsImageSkia(),
+ ideal_size);
// This calculation determines that the new image would have the correct
// height for width.
if (ideal_size != scaled_size) {
- proportional_image_view->set_border(views::Border::CreateSolidBorder(
+ proportional_image_view->SetBorder(views::Border::CreateSolidBorder(
message_center::kNotificationImageBorderSize, SK_ColorTRANSPARENT));
}
@@ -204,7 +195,7 @@ class NotificationProgressBar : public views::ProgressBar {
private:
// Overriden from View
- virtual gfx::Size GetPreferredSize() OVERRIDE;
+ virtual gfx::Size GetPreferredSize() const OVERRIDE;
virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE;
DISALLOW_COPY_AND_ASSIGN(NotificationProgressBar);
@@ -216,7 +207,7 @@ NotificationProgressBar::NotificationProgressBar() {
NotificationProgressBar::~NotificationProgressBar() {
}
-gfx::Size NotificationProgressBar::GetPreferredSize() {
+gfx::Size NotificationProgressBar::GetPreferredSize() const {
gfx::Size pref_size(kProgressBarWidth, message_center::kProgressBarThickness);
gfx::Insets insets = GetInsets();
pref_size.Enlarge(insets.width(), insets.height());
@@ -265,7 +256,6 @@ namespace message_center {
// static
NotificationView* NotificationView::Create(MessageCenterController* controller,
const Notification& notification,
- bool expanded,
bool top_level) {
switch (notification.type()) {
case NOTIFICATION_TYPE_BASE_FORMAT:
@@ -287,7 +277,7 @@ NotificationView* NotificationView::Create(MessageCenterController* controller,
// Currently all roads lead to the generic NotificationView.
NotificationView* notification_view =
- new NotificationView(controller, notification, expanded);
+ new NotificationView(controller, notification);
#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
// Don't create shadows for notification toasts on linux wih aura.
@@ -299,192 +289,86 @@ NotificationView* NotificationView::Create(MessageCenterController* controller,
return notification_view;
}
+void NotificationView::CreateOrUpdateViews(const Notification& notification) {
+ CreateOrUpdateTitleView(notification);
+ CreateOrUpdateMessageView(notification);
+ CreateOrUpdateContextMessageView(notification);
+ CreateOrUpdateProgressBarView(notification);
+ CreateOrUpdateListItemViews(notification);
+ CreateOrUpdateIconView(notification);
+ CreateOrUpdateImageView(notification);
+ CreateOrUpdateActionButtonViews(notification);
+}
+
+void NotificationView::SetAccessibleName(const Notification& notification) {
+ std::vector<base::string16> accessible_lines;
+ accessible_lines.push_back(notification.title());
+ accessible_lines.push_back(notification.message());
+ accessible_lines.push_back(notification.context_message());
+ std::vector<NotificationItem> items = notification.items();
+ for (size_t i = 0; i < items.size() && i < kNotificationMaximumItems; ++i) {
+ accessible_lines.push_back(items[i].title + base::ASCIIToUTF16(" ") +
+ items[i].message);
+ }
+ set_accessible_name(JoinString(accessible_lines, '\n'));
+}
+
NotificationView::NotificationView(MessageCenterController* controller,
- const Notification& notification,
- bool expanded)
+ const Notification& notification)
: MessageView(this,
notification.id(),
notification.notifier_id(),
+ notification.small_image().AsImageSkia(),
notification.display_source()),
controller_(controller),
clickable_(notification.clickable()),
- is_expanded_(expanded) {
- std::vector<string16> accessible_lines;
-
- // Create the opaque background that's above the view's shadow.
- background_view_ = new views::View();
- background_view_->set_background(MakeBackground());
-
+ top_view_(NULL),
+ title_view_(NULL),
+ message_view_(NULL),
+ context_message_view_(NULL),
+ icon_view_(NULL),
+ bottom_view_(NULL),
+ image_view_(NULL),
+ progress_bar_view_(NULL) {
// Create the top_view_, which collects into a vertical box all content
// at the top of the notification (to the right of the icon) except for the
// close button.
top_view_ = new views::View();
top_view_->SetLayoutManager(
new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0));
- top_view_->set_border(MakeEmptyBorder(
- kTextTopPadding - 8, 0, kTextBottomPadding - 5, 0));
-
- const gfx::FontList default_label_font_list = views::Label().font_list();
-
- // Create the title view if appropriate.
- title_view_ = NULL;
- if (!notification.title().empty()) {
- const gfx::FontList& font_list =
- default_label_font_list.DeriveFontListWithSizeDelta(2);
- int padding = kTitleLineHeight - font_list.GetHeight();
- title_view_ = new BoundedLabel(
- gfx::TruncateString(notification.title(), kTitleCharacterLimit),
- font_list);
- title_view_->SetLineHeight(kTitleLineHeight);
- title_view_->SetLineLimit(IsExperimentalNotificationUIEnabled() ?
- message_center::kExperimentalTitleLineLimit :
- message_center::kTitleLineLimit);
- title_view_->SetColors(message_center::kRegularTextColor,
- kRegularTextBackgroundColor);
- title_view_->set_border(MakeTextBorder(padding, 3, 0));
- top_view_->AddChildView(title_view_);
- accessible_lines.push_back(notification.title());
- }
-
- // Create the message view if appropriate.
- message_view_ = NULL;
- if (!notification.message().empty()) {
- int padding = kMessageLineHeight - default_label_font_list.GetHeight();
- message_view_ = new BoundedLabel(
- gfx::TruncateString(notification.message(), kMessageCharacterLimit));
- message_view_->SetLineHeight(kMessageLineHeight);
- message_view_->SetVisible(!is_expanded_ || !notification.items().size());
- message_view_->SetColors(message_center::kRegularTextColor,
- kDimTextBackgroundColor);
- message_view_->set_border(MakeTextBorder(padding, 4, 0));
- top_view_->AddChildView(message_view_);
- accessible_lines.push_back(notification.message());
- }
-
- // Create the context message view if appropriate.
- context_message_view_ = NULL;
- if (!notification.context_message().empty()) {
- int padding = kMessageLineHeight - default_label_font_list.GetHeight();
- context_message_view_ =
- new BoundedLabel(gfx::TruncateString(notification.context_message(),
- kContextMessageCharacterLimit),
- default_label_font_list);
- context_message_view_->SetLineLimit(
- message_center::kContextMessageLineLimit);
- context_message_view_->SetLineHeight(kMessageLineHeight);
- context_message_view_->SetColors(message_center::kDimTextColor,
- kContextTextBackgroundColor);
- context_message_view_->set_border(MakeTextBorder(padding, 4, 0));
- top_view_->AddChildView(context_message_view_);
- accessible_lines.push_back(notification.context_message());
- }
-
- // Create the progress bar view.
- progress_bar_view_ = NULL;
- if (notification.type() == NOTIFICATION_TYPE_PROGRESS) {
- progress_bar_view_ = new NotificationProgressBar();
- progress_bar_view_->set_border(MakeProgressBarBorder(
- message_center::kProgressBarTopPadding, kProgressBarBottomPadding));
- progress_bar_view_->SetValue(notification.progress() / 100.0);
- top_view_->AddChildView(progress_bar_view_);
- }
-
- // Create the list item views (up to a maximum).
- int padding = kMessageLineHeight - default_label_font_list.GetHeight();
- std::vector<NotificationItem> items = notification.items();
- for (size_t i = 0; i < items.size() && i < kNotificationMaximumItems; ++i) {
- ItemView* item_view = new ItemView(items[i]);
- item_view->SetVisible(is_expanded_);
- item_view->set_border(MakeTextBorder(padding, i ? 0 : 4, 0));
- item_views_.push_back(item_view);
- top_view_->AddChildView(item_view);
- accessible_lines.push_back(
- items[i].title + base::ASCIIToUTF16(" ") + items[i].message);
- }
-
- // Create the notification icon view.
- gfx::ImageSkia icon = notification.icon().AsImageSkia();
- if (notification.type() == NOTIFICATION_TYPE_SIMPLE &&
- (icon.width() != kIconSize ||
- icon.height() != kIconSize ||
- HasAlpha(icon, GetWidget()))) {
- views::ImageView* icon_view = new views::ImageView();
- icon_view->SetImage(icon);
- icon_view->SetImageSize(gfx::Size(kLegacyIconSize, kLegacyIconSize));
- icon_view->SetHorizontalAlignment(views::ImageView::CENTER);
- icon_view->SetVerticalAlignment(views::ImageView::CENTER);
- icon_view_ = icon_view;
- } else {
- icon_view_ = new ProportionalImageView(icon);
- }
-
- icon_view_->set_background(MakeBackground(kIconBackgroundColor));
-
+ top_view_->SetBorder(
+ MakeEmptyBorder(kTextTopPadding - 8, 0, kTextBottomPadding - 5, 0));
+ AddChildView(top_view_);
// Create the bottom_view_, which collects into a vertical box all content
- // below the notification icon except for the expand button.
+ // below the notification icon.
bottom_view_ = new views::View();
bottom_view_->SetLayoutManager(
new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0));
+ AddChildView(bottom_view_);
- // Create the image view if appropriate.
- image_view_ = NULL;
- if (!notification.image().IsEmpty()) {
- gfx::Size image_size(
- kNotificationPreferredImageWidth, kNotificationPreferredImageHeight);
- image_view_ = MakeNotificationImage(notification.image(), image_size);
- image_view_->SetVisible(is_expanded_);
- bottom_view_->AddChildView(image_view_);
- }
-
- // Create action buttons if appropriate.
- std::vector<ButtonInfo> buttons = notification.buttons();
- for (size_t i = 0; i < buttons.size(); ++i) {
- views::View* separator = new views::ImageView();
- separator->set_border(MakeSeparatorBorder(1, 0, kButtonSeparatorColor));
- bottom_view_->AddChildView(separator);
- NotificationButton* button = new NotificationButton(this);
- ButtonInfo button_info = buttons[i];
- button->SetTitle(button_info.title);
- button->SetIcon(button_info.icon.AsImageSkia());
- action_buttons_.push_back(button);
- bottom_view_->AddChildView(button);
- }
-
- // Create expand button
- expand_button_ = new PaddedButton(this);
- expand_button_->SetPadding(-kExpandIconRightPadding,
- -kExpandIconBottomPadding);
- expand_button_->SetNormalImage(IDR_NOTIFICATION_EXPAND);
- expand_button_->SetHoveredImage(IDR_NOTIFICATION_EXPAND_HOVER);
- expand_button_->SetPressedImage(IDR_NOTIFICATION_EXPAND_PRESSED);
- expand_button_->set_animate_on_state_change(false);
- expand_button_->SetAccessibleName(l10n_util::GetStringUTF16(
- IDS_MESSAGE_CENTER_EXPAND_NOTIFICATION_BUTTON_ACCESSIBLE_NAME));
+ CreateOrUpdateViews(notification);
// Put together the different content and control views. Layering those allows
- // for proper layout logic and it also allows the close and expand buttons to
- // overlap the content as needed to provide large enough click and touch areas
- // (<http://crbug.com/168822> and <http://crbug.com/168856>).
- AddChildView(background_view_);
- AddChildView(top_view_);
- AddChildView(icon_view_);
- AddChildView(bottom_view_);
+ // for proper layout logic and it also allows the close button and small
+ // image to overlap the content as needed to provide large enough click and
+ // touch areas (<http://crbug.com/168822> and <http://crbug.com/168856>).
+ AddChildView(small_image());
AddChildView(close_button());
- AddChildView(expand_button_);
- set_accessible_name(JoinString(accessible_lines, '\n'));
+ SetAccessibleName(notification);
}
NotificationView::~NotificationView() {
}
-gfx::Size NotificationView::GetPreferredSize() {
- int top_width = top_view_->GetPreferredSize().width();
+gfx::Size NotificationView::GetPreferredSize() const {
+ int top_width = top_view_->GetPreferredSize().width() +
+ icon_view_->GetPreferredSize().width();
int bottom_width = bottom_view_->GetPreferredSize().width();
int preferred_width = std::max(top_width, bottom_width) + GetInsets().width();
return gfx::Size(preferred_width, GetHeightForWidth(preferred_width));
}
-int NotificationView::GetHeightForWidth(int width) {
+int NotificationView::GetHeightForWidth(int width) const {
// Get the height assuming no line limit changes.
int content_width = width - GetInsets().width();
int top_height = top_view_->GetHeightForWidth(content_width);
@@ -494,8 +378,13 @@ int NotificationView::GetHeightForWidth(int width) {
// line limit would be different for the specified width than it currently is.
// TODO(dharcourt): Avoid BoxLayout and directly compute the correct height.
if (message_view_) {
+ int title_lines = 0;
+ if (title_view_) {
+ title_lines = title_view_->GetLinesForWidthAndLimit(width,
+ kMaxTitleLines);
+ }
int used_limit = message_view_->GetLineLimit();
- int correct_limit = GetMessageLineLimit(width);
+ int correct_limit = GetMessageLineLimit(title_lines, width);
if (used_limit != correct_limit) {
top_height -= GetMessageHeight(content_width, used_limit);
top_height += GetMessageHeight(content_width, correct_limit);
@@ -514,17 +403,18 @@ int NotificationView::GetHeightForWidth(int width) {
}
void NotificationView::Layout() {
+ MessageView::Layout();
gfx::Insets insets = GetInsets();
int content_width = width() - insets.width();
- int content_right = width() - insets.right();
// Before any resizing, set or adjust the number of message lines.
+ int title_lines = 0;
+ if (title_view_) {
+ title_lines =
+ title_view_->GetLinesForWidthAndLimit(width(), kMaxTitleLines);
+ }
if (message_view_)
- message_view_->SetLineLimit(GetMessageLineLimit(width()));
-
- // Background.
- background_view_->SetBounds(insets.left(), insets.top(),
- content_width, height() - insets.height());
+ message_view_->SetLineLimit(GetMessageLineLimit(title_lines, width()));
// Top views.
int top_height = top_view_->GetHeightForWidth(content_width);
@@ -538,18 +428,6 @@ void NotificationView::Layout() {
int bottom_height = bottom_view_->GetHeightForWidth(content_width);
bottom_view_->SetBounds(insets.left(), bottom_y,
content_width, bottom_height);
-
- // Close button.
- gfx::Size close_size(close_button()->GetPreferredSize());
- close_button()->SetBounds(content_right - close_size.width(), insets.top(),
- close_size.width(), close_size.height());
-
- // Expand button.
- gfx::Size expand_size(expand_button_->GetPreferredSize());
- int expand_y = bottom_y - expand_size.height();
- expand_button_->SetVisible(IsExpansionNeeded(width()));
- expand_button_->SetBounds(content_right - expand_size.width(), expand_y,
- expand_size.width(), expand_size.height());
}
void NotificationView::OnFocus() {
@@ -571,9 +449,9 @@ views::View* NotificationView::GetEventHandlerForRect(const gfx::Rect& rect) {
// Want to return this for underlying views, otherwise GetCursor is not
// called. But buttons are exceptions, they'll have their own event handlings.
- std::vector<views::View*> buttons(action_buttons_);
+ std::vector<views::View*> buttons(action_buttons_.begin(),
+ action_buttons_.end());
buttons.push_back(close_button());
- buttons.push_back(expand_button_);
for (size_t i = 0; i < buttons.size(); ++i) {
gfx::Point point_in_child = point;
@@ -589,38 +467,33 @@ gfx::NativeCursor NotificationView::GetCursor(const ui::MouseEvent& event) {
if (!clickable_ || !controller_->HasClickedListener(notification_id()))
return views::View::GetCursor(event);
-#if defined(USE_AURA)
- return ui::kCursorHand;
-#elif defined(OS_WIN)
- static HCURSOR g_hand_cursor = LoadCursor(NULL, IDC_HAND);
- return g_hand_cursor;
-#endif
+ return views::GetNativeHandCursor();
+}
+
+void NotificationView::UpdateWithNotification(
+ const Notification& notification) {
+ MessageView::UpdateWithNotification(notification);
+
+ CreateOrUpdateViews(notification);
+ SetAccessibleName(notification);
+ Layout();
+ SchedulePaint();
}
void NotificationView::ButtonPressed(views::Button* sender,
const ui::Event& event) {
+ // Certain operations can cause |this| to be destructed, so copy the members
+ // we send to other parts of the code.
+ // TODO(dewittj): Remove this hack.
+ std::string id(notification_id());
// See if the button pressed was an action button.
for (size_t i = 0; i < action_buttons_.size(); ++i) {
if (sender == action_buttons_[i]) {
- controller_->ClickOnNotificationButton(notification_id(), i);
+ controller_->ClickOnNotificationButton(id, i);
return;
}
}
- // Adjust notification subviews for expansion.
- if (sender == expand_button_) {
- if (message_view_ && item_views_.size())
- message_view_->SetVisible(false);
- for (size_t i = 0; i < item_views_.size(); ++i)
- item_views_[i]->SetVisible(true);
- if (image_view_)
- image_view_->SetVisible(true);
-
- is_expanded_ = true;
- controller_->ExpandNotification(notification_id());
- return;
- }
-
// Let the superclass handled anything other than action buttons.
// Warning: This may cause the NotificationView itself to be deleted,
// so don't do anything afterwards.
@@ -636,34 +509,256 @@ void NotificationView::RemoveNotification(const std::string& notification_id,
controller_->RemoveNotification(notification_id, by_user);
}
-void NotificationView::DisableNotificationsFromThisSource(
- const NotifierId& notifier_id) {
- controller_->DisableNotificationsFromThisSource(notifier_id);
+void NotificationView::CreateOrUpdateTitleView(
+ const Notification& notification) {
+ if (notification.title().empty()) {
+ if (title_view_) {
+ // Deletion will also remove |title_view_| from its parent.
+ delete title_view_;
+ title_view_ = NULL;
+ }
+ return;
+ }
+
+ DCHECK(top_view_ != NULL);
+
+ const gfx::FontList& font_list =
+ views::Label().font_list().DeriveWithSizeDelta(2);
+
+ int title_character_limit =
+ kNotificationWidth * kMaxTitleLines / kMinPixelsPerTitleCharacter;
+
+ if (!title_view_) {
+ int padding = kTitleLineHeight - font_list.GetHeight();
+
+ title_view_ = new BoundedLabel(
+ gfx::TruncateString(notification.title(), title_character_limit),
+ font_list);
+ title_view_->SetLineHeight(kTitleLineHeight);
+ title_view_->SetLineLimit(kMaxTitleLines);
+ title_view_->SetColors(message_center::kRegularTextColor,
+ kRegularTextBackgroundColor);
+ title_view_->SetBorder(MakeTextBorder(padding, 3, 0));
+ top_view_->AddChildView(title_view_);
+ } else {
+ title_view_->SetText(
+ gfx::TruncateString(notification.title(), title_character_limit));
+ }
+}
+
+void NotificationView::CreateOrUpdateMessageView(
+ const Notification& notification) {
+ if (notification.message().empty()) {
+ if (message_view_) {
+ // Deletion will also remove |message_view_| from its parent.
+ delete message_view_;
+ message_view_ = NULL;
+ }
+ return;
+ }
+
+ DCHECK(top_view_ != NULL);
+
+ if (!message_view_) {
+ int padding = kMessageLineHeight - views::Label().font_list().GetHeight();
+ message_view_ = new BoundedLabel(
+ gfx::TruncateString(notification.message(), kMessageCharacterLimit));
+ message_view_->SetLineHeight(kMessageLineHeight);
+ message_view_->SetColors(message_center::kRegularTextColor,
+ kDimTextBackgroundColor);
+ message_view_->SetBorder(MakeTextBorder(padding, 4, 0));
+ top_view_->AddChildView(message_view_);
+ } else {
+ message_view_->SetText(
+ gfx::TruncateString(notification.message(), kMessageCharacterLimit));
+ }
+
+ message_view_->SetVisible(!notification.items().size());
}
-void NotificationView::ShowNotifierSettingsBubble() {
- controller_->ShowNotifierSettingsBubble();
+void NotificationView::CreateOrUpdateContextMessageView(
+ const Notification& notification) {
+ if (notification.context_message().empty()) {
+ if (context_message_view_) {
+ // Deletion will also remove |context_message_view_| from its parent.
+ delete context_message_view_;
+ context_message_view_ = NULL;
+ }
+ return;
+ }
+
+ DCHECK(top_view_ != NULL);
+
+ if (!context_message_view_) {
+ int padding = kMessageLineHeight - views::Label().font_list().GetHeight();
+ context_message_view_ = new BoundedLabel(gfx::TruncateString(
+ notification.context_message(), kContextMessageCharacterLimit));
+ context_message_view_->SetLineLimit(
+ message_center::kContextMessageLineLimit);
+ context_message_view_->SetLineHeight(kMessageLineHeight);
+ context_message_view_->SetColors(message_center::kDimTextColor,
+ kContextTextBackgroundColor);
+ context_message_view_->SetBorder(MakeTextBorder(padding, 4, 0));
+ top_view_->AddChildView(context_message_view_);
+ } else {
+ context_message_view_->SetText(gfx::TruncateString(
+ notification.context_message(), kContextMessageCharacterLimit));
+ }
}
-bool NotificationView::IsExpansionNeeded(int width) {
- return (!is_expanded_ &&
- (image_view_ ||
- item_views_.size() ||
- IsMessageExpansionNeeded(width)));
+void NotificationView::CreateOrUpdateProgressBarView(
+ const Notification& notification) {
+ if (notification.type() != NOTIFICATION_TYPE_PROGRESS) {
+ if (progress_bar_view_) {
+ // Deletion will also remove |progress_bar_view_| from its parent.
+ delete progress_bar_view_;
+ progress_bar_view_ = NULL;
+ }
+ return;
+ }
+
+ DCHECK(top_view_ != NULL);
+
+ if (!progress_bar_view_) {
+ progress_bar_view_ = new NotificationProgressBar();
+ progress_bar_view_->SetBorder(MakeProgressBarBorder(
+ message_center::kProgressBarTopPadding, kProgressBarBottomPadding));
+ top_view_->AddChildView(progress_bar_view_);
+ }
+
+ progress_bar_view_->SetValue(notification.progress() / 100.0);
+ progress_bar_view_->SetVisible(!notification.items().size());
}
-bool NotificationView::IsMessageExpansionNeeded(int width) {
- int current = GetMessageLines(width, GetMessageLineLimit(width));
- int expanded = GetMessageLines(width,
- message_center::kMessageExpandedLineLimit);
- return current < expanded;
+void NotificationView::CreateOrUpdateListItemViews(
+ const Notification& notification) {
+ for (size_t i = 0; i < item_views_.size(); ++i)
+ delete item_views_[i];
+ item_views_.clear();
+
+ int padding = kMessageLineHeight - views::Label().font_list().GetHeight();
+ std::vector<NotificationItem> items = notification.items();
+
+ if (items.size() == 0)
+ return;
+
+ DCHECK(top_view_);
+ for (size_t i = 0; i < items.size() && i < kNotificationMaximumItems; ++i) {
+ ItemView* item_view = new ItemView(items[i]);
+ item_view->SetBorder(MakeTextBorder(padding, i ? 0 : 4, 0));
+ item_views_.push_back(item_view);
+ top_view_->AddChildView(item_view);
+ }
}
-int NotificationView::GetMessageLineLimit(int width) {
- // Expanded notifications get a larger limit, except for image notifications,
- // whose images must be kept flush against their icons.
- if (is_expanded_ && !image_view_)
- return message_center::kMessageExpandedLineLimit;
+void NotificationView::CreateOrUpdateIconView(
+ const Notification& notification) {
+ if (icon_view_) {
+ delete icon_view_;
+ icon_view_ = NULL;
+ }
+
+ // TODO(dewittj): Detect a compatible update and use the existing icon view.
+ gfx::ImageSkia icon = notification.icon().AsImageSkia();
+ if (notification.type() == NOTIFICATION_TYPE_SIMPLE &&
+ (icon.width() != kIconSize || icon.height() != kIconSize ||
+ HasAlpha(icon, GetWidget()))) {
+ views::ImageView* icon_view = new views::ImageView();
+ icon_view->SetImage(icon);
+ icon_view->SetImageSize(gfx::Size(kLegacyIconSize, kLegacyIconSize));
+ icon_view->SetHorizontalAlignment(views::ImageView::CENTER);
+ icon_view->SetVerticalAlignment(views::ImageView::CENTER);
+ icon_view_ = icon_view;
+ } else {
+ icon_view_ =
+ new ProportionalImageView(icon, gfx::Size(kIconSize, kIconSize));
+ }
+
+ icon_view_->set_background(
+ views::Background::CreateSolidBackground(kIconBackgroundColor));
+
+ AddChildView(icon_view_);
+}
+
+void NotificationView::CreateOrUpdateImageView(
+ const Notification& notification) {
+ if (image_view_) {
+ delete image_view_;
+ image_view_ = NULL;
+ }
+
+ DCHECK(bottom_view_);
+ DCHECK_EQ(this, bottom_view_->parent());
+
+ // TODO(dewittj): Detect a compatible update and use the existing image view.
+ if (!notification.image().IsEmpty()) {
+ gfx::Size image_size(kNotificationPreferredImageWidth,
+ kNotificationPreferredImageHeight);
+ image_view_ = MakeNotificationImage(notification.image(), image_size);
+ bottom_view_->AddChildViewAt(image_view_, 0);
+ }
+}
+
+void NotificationView::CreateOrUpdateActionButtonViews(
+ const Notification& notification) {
+ std::vector<ButtonInfo> buttons = notification.buttons();
+ bool new_buttons = action_buttons_.size() != buttons.size();
+
+ if (new_buttons || buttons.size() == 0) {
+ // STLDeleteElements also clears the container.
+ STLDeleteElements(&separators_);
+ STLDeleteElements(&action_buttons_);
+ }
+
+ DCHECK(bottom_view_);
+ DCHECK_EQ(this, bottom_view_->parent());
+
+ for (size_t i = 0; i < buttons.size(); ++i) {
+ ButtonInfo button_info = buttons[i];
+ if (new_buttons) {
+ views::View* separator = new views::ImageView();
+ separator->SetBorder(MakeSeparatorBorder(1, 0, kButtonSeparatorColor));
+ separators_.push_back(separator);
+ bottom_view_->AddChildView(separator);
+ NotificationButton* button = new NotificationButton(this);
+ button->SetTitle(button_info.title);
+ button->SetIcon(button_info.icon.AsImageSkia());
+ action_buttons_.push_back(button);
+ bottom_view_->AddChildView(button);
+ } else {
+ action_buttons_[i]->SetTitle(button_info.title);
+ action_buttons_[i]->SetIcon(button_info.icon.AsImageSkia());
+ action_buttons_[i]->SchedulePaint();
+ action_buttons_[i]->Layout();
+ }
+ }
+
+ if (new_buttons) {
+ Layout();
+ views::Widget* widget = GetWidget();
+ if (widget != NULL) {
+ widget->SetSize(widget->GetContentsView()->GetPreferredSize());
+ GetWidget()->SynthesizeMouseMoveEvent();
+ }
+ }
+}
+
+int NotificationView::GetMessageLineLimit(int title_lines, int width) const {
+ // Image notifications require that the image must be kept flush against
+ // their icons, but we can allow more text if no image.
+ int effective_title_lines = std::max(0, title_lines - 1);
+ int line_reduction_from_title = (image_view_ ? 1 : 2) * effective_title_lines;
+ if (!image_view_) {
+ // Title lines are counted as twice as big as message lines for the purpose
+ // of this calculation.
+ // The effect from the title reduction here should be:
+ // * 0 title lines: 5 max lines message.
+ // * 1 title line: 5 max lines message.
+ // * 2 title lines: 3 max lines message.
+ return std::max(
+ 0,
+ message_center::kMessageExpandedLineLimit - line_reduction_from_title);
+ }
int message_line_limit = message_center::kMessageCollapsedLineLimit;
@@ -674,16 +769,17 @@ int NotificationView::GetMessageLineLimit(int width) {
message_center::kContextMessageLineLimit);
}
- DCHECK_GT(message_line_limit, 0);
- return message_line_limit;
-}
+ // The effect from the title reduction here should be:
+ // * 0 title lines: 2 max lines message + context message.
+ // * 1 title line: 2 max lines message + context message.
+ // * 2 title lines: 1 max lines message + context message.
+ message_line_limit =
+ std::max(0, message_line_limit - line_reduction_from_title);
-int NotificationView::GetMessageLines(int width, int limit) {
- return message_view_ ?
- message_view_->GetLinesForWidthAndLimit(width, limit) : 0;
+ return message_line_limit;
}
-int NotificationView::GetMessageHeight(int width, int limit) {
+int NotificationView::GetMessageHeight(int width, int limit) const {
return message_view_ ?
message_view_->GetSizeForWidthAndLines(width, limit).height() : 0;
}
diff --git a/chromium/ui/message_center/views/notification_view.h b/chromium/ui/message_center/views/notification_view.h
index ba47dda9706..2d6913124cc 100644
--- a/chromium/ui/message_center/views/notification_view.h
+++ b/chromium/ui/message_center/views/notification_view.h
@@ -19,6 +19,7 @@ namespace message_center {
class BoundedLabel;
class MessageCenter;
class MessageCenterController;
+class NotificationButton;
class NotificationView;
class PaddedButton;
@@ -38,14 +39,12 @@ class MESSAGE_CENTER_EXPORT NotificationView : public MessageView,
// |controller| may be NULL, but has to be set before the view is shown.
static NotificationView* Create(MessageCenterController* controller,
const Notification& notification,
- bool expanded,
bool top_level);
-
- virtual ~NotificationView();
+ virtual ~NotificationView();
// Overridden from views::View:
- virtual gfx::Size GetPreferredSize() OVERRIDE;
- virtual int GetHeightForWidth(int width) OVERRIDE;
+ virtual gfx::Size GetPreferredSize() const OVERRIDE;
+ virtual int GetHeightForWidth(int width) const OVERRIDE;
virtual void Layout() OVERRIDE;
virtual void OnFocus() OVERRIDE;
virtual void ScrollRectToVisible(const gfx::Rect& rect) OVERRIDE;
@@ -53,6 +52,8 @@ class MESSAGE_CENTER_EXPORT NotificationView : public MessageView,
virtual gfx::NativeCursor GetCursor(const ui::MouseEvent& event) OVERRIDE;
// Overridden from MessageView:
+ virtual void UpdateWithNotification(
+ const Notification& notification) OVERRIDE;
virtual void ButtonPressed(views::Button* sender,
const ui::Event& event) OVERRIDE;
@@ -60,9 +61,6 @@ class MESSAGE_CENTER_EXPORT NotificationView : public MessageView,
virtual void ClickOnNotification(const std::string& notification_id) OVERRIDE;
virtual void RemoveNotification(const std::string& notification_id,
bool by_user) OVERRIDE;
- virtual void DisableNotificationsFromThisSource(
- const NotifierId& notifier_id) OVERRIDE;
- virtual void ShowNotifierSettingsBubble() OVERRIDE;
void set_controller(MessageCenterController* controller) {
controller_ = controller;
@@ -70,24 +68,37 @@ class MESSAGE_CENTER_EXPORT NotificationView : public MessageView,
protected:
NotificationView(MessageCenterController* controller,
- const Notification& notification,
- bool expanded);
+ const Notification& notification);
private:
- bool IsExpansionNeeded(int width);
- bool IsMessageExpansionNeeded(int width);
- int GetMessageLineLimit(int width);
- int GetMessageLines(int width, int limit);
- int GetMessageHeight(int width, int limit);
+ FRIEND_TEST_ALL_PREFIXES(NotificationViewTest, CreateOrUpdateTest);
+ FRIEND_TEST_ALL_PREFIXES(NotificationViewTest, TestLineLimits);
+ FRIEND_TEST_ALL_PREFIXES(NotificationViewTest, UpdateButtonsStateTest);
+ FRIEND_TEST_ALL_PREFIXES(NotificationViewTest, UpdateButtonCountTest);
+
+ friend class NotificationViewTest;
+
+ void CreateOrUpdateViews(const Notification& notification);
+ void SetAccessibleName(const Notification& notification);
+
+ void CreateOrUpdateTitleView(const Notification& notification);
+ void CreateOrUpdateMessageView(const Notification& notification);
+ void CreateOrUpdateContextMessageView(const Notification& notification);
+ void CreateOrUpdateProgressBarView(const Notification& notification);
+ void CreateOrUpdateListItemViews(const Notification& notification);
+ void CreateOrUpdateIconView(const Notification& notification);
+ void CreateOrUpdateImageView(const Notification& notification);
+ void CreateOrUpdateActionButtonViews(const Notification& notification);
+
+ int GetMessageLineLimit(int title_lines, int width) const;
+ int GetMessageHeight(int width, int limit) const;
MessageCenterController* controller_; // Weak, lives longer then views.
// Describes whether the view should display a hand pointer or not.
bool clickable_;
- bool is_expanded_;
// Weak references to NotificationView descendants owned by their parents.
- views::View* background_view_;
views::View* top_view_;
BoundedLabel* title_view_;
BoundedLabel* message_view_;
@@ -97,8 +108,8 @@ class MESSAGE_CENTER_EXPORT NotificationView : public MessageView,
views::View* bottom_view_;
views::View* image_view_;
views::ProgressBar* progress_bar_view_;
- std::vector<views::View*> action_buttons_;
- PaddedButton* expand_button_;
+ std::vector<NotificationButton*> action_buttons_;
+ std::vector<views::View*> separators_;
DISALLOW_COPY_AND_ASSIGN(NotificationView);
};
diff --git a/chromium/ui/message_center/views/notification_view_unittest.cc b/chromium/ui/message_center/views/notification_view_unittest.cc
new file mode 100644
index 00000000000..b6d67526905
--- /dev/null
+++ b/chromium/ui/message_center/views/notification_view_unittest.cc
@@ -0,0 +1,323 @@
+// 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 "ui/message_center/views/notification_view.h"
+
+#include "base/memory/scoped_ptr.h"
+#include "base/strings/utf_string_conversions.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+#include "ui/gfx/image/image.h"
+#include "ui/message_center/notification.h"
+#include "ui/message_center/notification_list.h"
+#include "ui/message_center/notification_types.h"
+#include "ui/message_center/views/message_center_controller.h"
+#include "ui/message_center/views/notification_button.h"
+#include "ui/views/layout/fill_layout.h"
+#include "ui/views/test/views_test_base.h"
+#include "ui/views/widget/widget_delegate.h"
+
+namespace message_center {
+
+/* Test fixture ***************************************************************/
+
+class NotificationViewTest : public views::ViewsTestBase,
+ public MessageCenterController {
+ public:
+ NotificationViewTest();
+ virtual ~NotificationViewTest();
+
+ virtual void SetUp() OVERRIDE;
+ virtual void TearDown() OVERRIDE;
+
+ views::Widget* widget() { return notification_view_->GetWidget(); }
+ NotificationView* notification_view() { return notification_view_.get(); }
+ Notification* notification() { return notification_.get(); }
+ RichNotificationData* data() { return data_.get(); }
+
+ // Overridden from MessageCenterController:
+ virtual void ClickOnNotification(const std::string& notification_id) OVERRIDE;
+ virtual void RemoveNotification(const std::string& notification_id,
+ bool by_user) OVERRIDE;
+ virtual scoped_ptr<ui::MenuModel> CreateMenuModel(
+ const NotifierId& notifier_id,
+ const base::string16& display_source) OVERRIDE;
+ virtual bool HasClickedListener(const std::string& notification_id) OVERRIDE;
+ virtual void ClickOnNotificationButton(const std::string& notification_id,
+ int button_index) OVERRIDE;
+
+ protected:
+ const gfx::Image CreateTestImage(int width, int height) {
+ return gfx::Image::CreateFrom1xBitmap(CreateBitmap(width, height));
+ }
+
+ const SkBitmap CreateBitmap(int width, int height) {
+ SkBitmap bitmap;
+ bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height);
+ bitmap.allocPixels();
+ bitmap.eraseRGB(0, 255, 0);
+ return bitmap;
+ }
+
+ std::vector<ButtonInfo> CreateButtons(int number) {
+ ButtonInfo info(base::ASCIIToUTF16("Test button title."));
+ info.icon = CreateTestImage(4, 4);
+ return std::vector<ButtonInfo>(number, info);
+ }
+
+ void CheckVerticalOrderInNotification() {
+ std::vector<views::View*> vertical_order;
+ vertical_order.push_back(notification_view()->top_view_);
+ vertical_order.push_back(notification_view()->image_view_);
+ std::copy(notification_view()->action_buttons_.begin(),
+ notification_view()->action_buttons_.end(),
+ std::back_inserter(vertical_order));
+ std::vector<views::View*>::iterator current = vertical_order.begin();
+ std::vector<views::View*>::iterator last = current++;
+ while (current != vertical_order.end()) {
+ gfx::Point last_point = (*last)->bounds().origin();
+ views::View::ConvertPointToTarget(
+ (*last), notification_view(), &last_point);
+
+ gfx::Point current_point = (*current)->bounds().origin();
+ views::View::ConvertPointToTarget(
+ (*current), notification_view(), &current_point);
+
+ EXPECT_LT(last_point.y(), current_point.y());
+ last = current++;
+ }
+ }
+
+ void UpdateNotificationViews() {
+ notification_view()->CreateOrUpdateViews(*notification());
+ notification_view()->Layout();
+ }
+
+ private:
+ scoped_ptr<RichNotificationData> data_;
+ scoped_ptr<Notification> notification_;
+ scoped_ptr<NotificationView> notification_view_;
+
+ DISALLOW_COPY_AND_ASSIGN(NotificationViewTest);
+};
+
+NotificationViewTest::NotificationViewTest() {
+}
+
+NotificationViewTest::~NotificationViewTest() {
+}
+
+void NotificationViewTest::SetUp() {
+ views::ViewsTestBase::SetUp();
+ // Create a dummy notification.
+ SkBitmap bitmap;
+ data_.reset(new RichNotificationData());
+ notification_.reset(
+ new Notification(NOTIFICATION_TYPE_BASE_FORMAT,
+ std::string("notification id"),
+ base::UTF8ToUTF16("title"),
+ base::UTF8ToUTF16("message"),
+ CreateTestImage(80, 80),
+ base::UTF8ToUTF16("display source"),
+ NotifierId(NotifierId::APPLICATION, "extension_id"),
+ *data_,
+ NULL));
+ notification_->set_small_image(CreateTestImage(16, 16));
+ notification_->set_image(CreateTestImage(320, 240));
+
+ // Then create a new NotificationView with that single notification.
+ notification_view_.reset(
+ NotificationView::Create(this, *notification_, true));
+ notification_view_->set_owned_by_client();
+
+ views::Widget::InitParams init_params(
+ CreateParams(views::Widget::InitParams::TYPE_POPUP));
+ views::Widget* widget = new views::Widget();
+ widget->Init(init_params);
+ widget->SetContentsView(notification_view_.get());
+ widget->SetSize(notification_view_->GetPreferredSize());
+}
+
+void NotificationViewTest::TearDown() {
+ widget()->Close();
+ notification_view_.reset();
+ views::ViewsTestBase::TearDown();
+}
+
+void NotificationViewTest::ClickOnNotification(
+ const std::string& notification_id) {
+ // For this test, this method should not be invoked.
+ NOTREACHED();
+}
+
+void NotificationViewTest::RemoveNotification(
+ const std::string& notification_id,
+ bool by_user) {
+ // For this test, this method should not be invoked.
+ NOTREACHED();
+}
+
+scoped_ptr<ui::MenuModel> NotificationViewTest::CreateMenuModel(
+ const NotifierId& notifier_id,
+ const base::string16& display_source) {
+ // For this test, this method should not be invoked.
+ NOTREACHED();
+ return scoped_ptr<ui::MenuModel>();
+}
+
+bool NotificationViewTest::HasClickedListener(
+ const std::string& notification_id) {
+ return true;
+}
+
+void NotificationViewTest::ClickOnNotificationButton(
+ const std::string& notification_id,
+ int button_index) {
+ // For this test, this method should not be invoked.
+ NOTREACHED();
+}
+
+/* Unit tests *****************************************************************/
+
+TEST_F(NotificationViewTest, CreateOrUpdateTest) {
+ EXPECT_TRUE(NULL != notification_view()->title_view_);
+ EXPECT_TRUE(NULL != notification_view()->message_view_);
+ EXPECT_TRUE(NULL != notification_view()->icon_view_);
+ EXPECT_TRUE(NULL != notification_view()->image_view_);
+
+ notification()->set_image(gfx::Image());
+ notification()->set_title(base::ASCIIToUTF16(""));
+ notification()->set_message(base::ASCIIToUTF16(""));
+ notification()->set_icon(gfx::Image());
+
+ notification_view()->CreateOrUpdateViews(*notification());
+ EXPECT_TRUE(NULL == notification_view()->title_view_);
+ EXPECT_TRUE(NULL == notification_view()->message_view_);
+ EXPECT_TRUE(NULL == notification_view()->image_view_);
+ // We still expect an icon view for all layouts.
+ EXPECT_TRUE(NULL != notification_view()->icon_view_);
+}
+
+TEST_F(NotificationViewTest, TestLineLimits) {
+ notification()->set_image(CreateTestImage(0, 0));
+ notification()->set_context_message(base::ASCIIToUTF16(""));
+ notification_view()->CreateOrUpdateViews(*notification());
+
+ EXPECT_EQ(5, notification_view()->GetMessageLineLimit(0, 360));
+ EXPECT_EQ(5, notification_view()->GetMessageLineLimit(1, 360));
+ EXPECT_EQ(3, notification_view()->GetMessageLineLimit(2, 360));
+
+ notification()->set_image(CreateTestImage(2, 2));
+ notification_view()->CreateOrUpdateViews(*notification());
+
+ EXPECT_EQ(2, notification_view()->GetMessageLineLimit(0, 360));
+ EXPECT_EQ(2, notification_view()->GetMessageLineLimit(1, 360));
+ EXPECT_EQ(1, notification_view()->GetMessageLineLimit(2, 360));
+
+ notification()->set_context_message(base::UTF8ToUTF16("foo"));
+ notification_view()->CreateOrUpdateViews(*notification());
+
+ EXPECT_TRUE(notification_view()->context_message_view_ != NULL);
+
+ EXPECT_EQ(1, notification_view()->GetMessageLineLimit(0, 360));
+ EXPECT_EQ(1, notification_view()->GetMessageLineLimit(1, 360));
+ EXPECT_EQ(0, notification_view()->GetMessageLineLimit(2, 360));
+}
+
+TEST_F(NotificationViewTest, UpdateButtonsStateTest) {
+ notification()->set_buttons(CreateButtons(2));
+ notification_view()->CreateOrUpdateViews(*notification());
+ widget()->Show();
+
+ EXPECT_TRUE(NULL == notification_view()->action_buttons_[0]->background());
+
+ // Now construct a mouse move event 1 pixel inside the boundary of the action
+ // button.
+ gfx::Point cursor_location(1, 1);
+ views::View::ConvertPointToWidget(notification_view()->action_buttons_[0],
+ &cursor_location);
+ ui::MouseEvent move(ui::ET_MOUSE_MOVED,
+ cursor_location,
+ cursor_location,
+ ui::EF_NONE,
+ ui::EF_NONE);
+ widget()->OnMouseEvent(&move);
+
+ EXPECT_TRUE(NULL != notification_view()->action_buttons_[0]->background());
+
+ notification_view()->CreateOrUpdateViews(*notification());
+
+ EXPECT_TRUE(NULL != notification_view()->action_buttons_[0]->background());
+
+ // Now construct a mouse move event 1 pixel outside the boundary of the
+ // widget.
+ cursor_location = gfx::Point(-1, -1);
+ move = ui::MouseEvent(ui::ET_MOUSE_MOVED,
+ cursor_location,
+ cursor_location,
+ ui::EF_NONE,
+ ui::EF_NONE);
+ widget()->OnMouseEvent(&move);
+
+ EXPECT_TRUE(NULL == notification_view()->action_buttons_[0]->background());
+}
+
+TEST_F(NotificationViewTest, UpdateButtonCountTest) {
+ notification()->set_buttons(CreateButtons(2));
+ notification_view()->CreateOrUpdateViews(*notification());
+ widget()->Show();
+
+ EXPECT_TRUE(NULL == notification_view()->action_buttons_[0]->background());
+ EXPECT_TRUE(NULL == notification_view()->action_buttons_[1]->background());
+
+ // Now construct a mouse move event 1 pixel inside the boundary of the action
+ // button.
+ gfx::Point cursor_location(1, 1);
+ views::View::ConvertPointToWidget(notification_view()->action_buttons_[0],
+ &cursor_location);
+ ui::MouseEvent move(ui::ET_MOUSE_MOVED,
+ cursor_location,
+ cursor_location,
+ ui::EF_NONE,
+ ui::EF_NONE);
+ widget()->OnMouseEvent(&move);
+
+ EXPECT_TRUE(NULL != notification_view()->action_buttons_[0]->background());
+ EXPECT_TRUE(NULL == notification_view()->action_buttons_[1]->background());
+
+ notification()->set_buttons(CreateButtons(1));
+ notification_view()->CreateOrUpdateViews(*notification());
+
+ EXPECT_TRUE(NULL != notification_view()->action_buttons_[0]->background());
+ EXPECT_EQ(1u, notification_view()->action_buttons_.size());
+
+ // Now construct a mouse move event 1 pixel outside the boundary of the
+ // widget.
+ cursor_location = gfx::Point(-1, -1);
+ move = ui::MouseEvent(ui::ET_MOUSE_MOVED,
+ cursor_location,
+ cursor_location,
+ ui::EF_NONE,
+ ui::EF_NONE);
+ widget()->OnMouseEvent(&move);
+
+ EXPECT_TRUE(NULL == notification_view()->action_buttons_[0]->background());
+}
+
+TEST_F(NotificationViewTest, ViewOrderingTest) {
+ // Tests that views are created in the correct vertical order.
+ notification()->set_buttons(CreateButtons(2));
+
+ // Layout the initial views.
+ UpdateNotificationViews();
+
+ // Double-check that vertical order is correct.
+ CheckVerticalOrderInNotification();
+
+ // Tests that views remain in that order even after an update.
+ UpdateNotificationViews();
+ CheckVerticalOrderInNotification();
+}
+
+} // namespace message_center
diff --git a/chromium/ui/message_center/views/notifier_settings_view.cc b/chromium/ui/message_center/views/notifier_settings_view.cc
index e345d93e501..a282ccbe04a 100644
--- a/chromium/ui/message_center/views/notifier_settings_view.cc
+++ b/chromium/ui/message_center/views/notifier_settings_view.cc
@@ -28,6 +28,7 @@
#include "ui/views/controls/button/custom_button.h"
#include "ui/views/controls/button/label_button_border.h"
#include "ui/views/controls/button/menu_button.h"
+#include "ui/views/controls/button/text_button.h"
#include "ui/views/controls/image_view.h"
#include "ui/views/controls/label.h"
#include "ui/views/controls/link.h"
@@ -41,10 +42,6 @@
#include "ui/views/painter.h"
#include "ui/views/widget/widget.h"
-#if defined(USE_AURA)
-#include "ui/aura/window.h"
-#endif
-
namespace message_center {
namespace settings {
@@ -141,8 +138,8 @@ class EntryView : public views::View {
// views::View:
virtual void Layout() OVERRIDE;
- virtual gfx::Size GetPreferredSize() OVERRIDE;
- virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE;
+ virtual gfx::Size GetPreferredSize() const OVERRIDE;
+ virtual void GetAccessibleState(ui::AXViewState* state) OVERRIDE;
virtual void OnFocus() OVERRIDE;
virtual bool OnKeyPressed(const ui::KeyEvent& event) OVERRIDE;
virtual bool OnKeyReleased(const ui::KeyEvent& event) OVERRIDE;
@@ -171,14 +168,14 @@ void EntryView::Layout() {
content->SetBounds(0, y, content_width, content_height);
}
-gfx::Size EntryView::GetPreferredSize() {
+gfx::Size EntryView::GetPreferredSize() const {
DCHECK_EQ(1, child_count());
gfx::Size size = child_at(0)->GetPreferredSize();
size.SetToMax(gfx::Size(settings::kWidth, settings::kEntryHeight));
return size;
}
-void EntryView::GetAccessibleState(ui::AccessibleViewState* state) {
+void EntryView::GetAccessibleState(ui::AXViewState* state) {
DCHECK_EQ(1, child_count());
child_at(0)->GetAccessibleState(state);
}
@@ -295,7 +292,7 @@ NotifierSettingsView::NotifierButton::NotifierButton(
notifier_(notifier),
icon_view_(new views::ImageView()),
name_view_(new views::Label(notifier_->name)),
- checkbox_(new views::Checkbox(string16())),
+ checkbox_(new views::Checkbox(base::string16())),
learn_more_(NULL) {
DCHECK(provider);
DCHECK(notifier);
@@ -333,7 +330,7 @@ NotifierSettingsView::NotifierButton::NotifierButton(
(settings::kLearnMoreTargetHeight - settings::kLearnMoreSize) / 2;
// The image itself is quite small, this large invisible border creates a
// much bigger click target.
- learn_more_->set_border(
+ learn_more_->SetBorder(
views::Border::CreateEmptyBorder(learn_more_border_height,
learn_more_border_width,
learn_more_border_height,
@@ -384,7 +381,8 @@ void NotifierSettingsView::NotifierButton::SendLearnMorePressedForTest() {
return;
gfx::Point point(110, 120);
ui::MouseEvent pressed(
- ui::ET_MOUSE_PRESSED, point, point, ui::EF_LEFT_MOUSE_BUTTON);
+ ui::ET_MOUSE_PRESSED, point, point, ui::EF_LEFT_MOUSE_BUTTON,
+ ui::EF_LEFT_MOUSE_BUTTON);
ButtonPressed(learn_more_, pressed);
}
@@ -405,7 +403,7 @@ void NotifierSettingsView::NotifierButton::ButtonPressed(
}
void NotifierSettingsView::NotifierButton::GetAccessibleState(
- ui::AccessibleViewState* state) {
+ ui::AXViewState* state) {
static_cast<views::View*>(checkbox_)->GetAccessibleState(state);
}
@@ -486,17 +484,15 @@ NotifierSettingsView::NotifierSettingsView(NotifierSettingsProvider* provider)
SetFocusable(true);
set_background(
views::Background::CreateSolidBackground(kMessageCenterBackgroundColor));
- if (get_use_acceleration_when_possible())
- SetPaintToLayer(true);
+ SetPaintToLayer(true);
- gfx::Font title_font =
- ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::MediumFont);
title_label_ = new views::Label(
l10n_util::GetStringUTF16(IDS_MESSAGE_CENTER_SETTINGS_BUTTON_LABEL),
- title_font);
+ ui::ResourceBundle::GetSharedInstance().GetFontList(
+ ui::ResourceBundle::MediumFont));
title_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
title_label_->SetMultiLine(true);
- title_label_->set_border(
+ title_label_->SetBorder(
views::Border::CreateEmptyBorder(kComputedTitleTopMargin,
settings::kTitleMargin,
kComputedTitleBottomMargin,
@@ -545,6 +541,9 @@ void NotifierSettingsView::NotifierGroupChanged() {
UpdateContentsView(notifiers);
}
+void NotifierSettingsView::NotifierEnabledChanged(const NotifierId& notifier_id,
+ bool enabled) {}
+
void NotifierSettingsView::UpdateContentsView(
const std::vector<Notifier*>& notifiers) {
buttons_.clear();
@@ -571,7 +570,7 @@ void NotifierSettingsView::UpdateContentsView(
top_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
top_label->SetMultiLine(true);
- top_label->set_border(views::Border::CreateEmptyBorder(
+ top_label->SetBorder(views::Border::CreateEmptyBorder(
0,
settings::kTitleMargin + kMenuButtonInnateMargin,
0,
@@ -580,7 +579,7 @@ void NotifierSettingsView::UpdateContentsView(
if (need_account_switcher) {
const NotifierGroup& active_group = provider_->GetActiveNotifierGroup();
- string16 notifier_group_text = active_group.login_info.empty() ?
+ base::string16 notifier_group_text = active_group.login_info.empty() ?
active_group.name : active_group.login_info;
notifier_group_selector_ =
new views::MenuButton(NULL, notifier_group_text, this, true);
@@ -598,7 +597,8 @@ void NotifierSettingsView::UpdateContentsView(
selector_border->SetInsets(gfx::Insets(
kMenuButtonVerticalPadding, kMenuButtonLeftPadding,
kMenuButtonVerticalPadding, kMenuButtonRightPadding));
- notifier_group_selector_->set_border(selector_border.release());
+ notifier_group_selector_->SetBorder(
+ selector_border.PassAs<views::Border>());
notifier_group_selector_->SetFocusPainter(scoped_ptr<views::Painter>());
notifier_group_selector_->set_animate_on_state_change(false);
notifier_group_selector_->SetFocusable(true);
@@ -616,17 +616,17 @@ void NotifierSettingsView::UpdateContentsView(
// border on the last notifier, as the spec leaves a space for it.
scoped_ptr<views::Border> entry_border;
if (i == notifier_count - 1) {
- entry_border.reset(views::Border::CreateEmptyBorder(
- 0, 0, settings::kEntrySeparatorHeight, 0));
+ entry_border = views::Border::CreateEmptyBorder(
+ 0, 0, settings::kEntrySeparatorHeight, 0);
} else {
- entry_border.reset(views::Border::CreateSolidSidedBorder(
- 0,
- 0,
- settings::kEntrySeparatorHeight,
- 0,
- settings::kEntrySeparatorColor));
+ entry_border =
+ views::Border::CreateSolidSidedBorder(0,
+ 0,
+ settings::kEntrySeparatorHeight,
+ 0,
+ settings::kEntrySeparatorColor);
}
- entry->set_border(entry_border.release());
+ entry->SetBorder(entry_border.Pass());
entry->SetFocusable(true);
contents_view->AddChildView(entry);
buttons_.insert(button);
@@ -656,7 +656,7 @@ void NotifierSettingsView::Layout() {
scroller_->SetBounds(0, title_height, width(), height() - title_height);
}
-gfx::Size NotifierSettingsView::GetMinimumSize() {
+gfx::Size NotifierSettingsView::GetMinimumSize() const {
gfx::Size size(settings::kWidth, settings::kMinimumHeight);
int total_height = title_label_->GetPreferredSize().height() +
scroller_->contents()->GetPreferredSize().height();
@@ -665,7 +665,7 @@ gfx::Size NotifierSettingsView::GetMinimumSize() {
return size;
}
-gfx::Size NotifierSettingsView::GetPreferredSize() {
+gfx::Size NotifierSettingsView::GetPreferredSize() const {
gfx::Size preferred_size;
gfx::Size title_size = title_label_->GetPreferredSize();
gfx::Size content_size = scroller_->contents()->GetPreferredSize();
@@ -717,7 +717,7 @@ void NotifierSettingsView::OnMenuButtonClicked(views::View* source,
notifier_group_menu_runner_->RunMenuAt(GetWidget(),
notifier_group_selector_,
menu_anchor,
- views::MenuItemView::BUBBLE_ABOVE,
+ views::MENU_ANCHOR_BUBBLE_ABOVE,
ui::MENU_SOURCE_MOUSE,
views::MenuRunner::CONTEXT_MENU))
return;
diff --git a/chromium/ui/message_center/views/notifier_settings_view.h b/chromium/ui/message_center/views/notifier_settings_view.h
index 665bed0a155..994fa50a6e9 100644
--- a/chromium/ui/message_center/views/notifier_settings_view.h
+++ b/chromium/ui/message_center/views/notifier_settings_view.h
@@ -43,6 +43,8 @@ class MESSAGE_CENTER_EXPORT NotifierSettingsView
virtual void UpdateIconImage(const NotifierId& notifier_id,
const gfx::Image& icon) OVERRIDE;
virtual void NotifierGroupChanged() OVERRIDE;
+ virtual void NotifierEnabledChanged(const NotifierId& notifier_id,
+ bool enabled) OVERRIDE;
void set_provider(NotifierSettingsProvider* new_provider) {
provider_ = new_provider;
@@ -71,7 +73,7 @@ class MESSAGE_CENTER_EXPORT NotifierSettingsView
// Overridden from views::ButtonListener:
virtual void ButtonPressed(views::Button* button,
const ui::Event& event) OVERRIDE;
- virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE;
+ virtual void GetAccessibleState(ui::AXViewState* state) OVERRIDE;
bool ShouldHaveLearnMoreButton() const;
// Helper function to reset the layout when the view has substantially
@@ -95,8 +97,8 @@ class MESSAGE_CENTER_EXPORT NotifierSettingsView
// Overridden from views::View:
virtual void Layout() OVERRIDE;
- virtual gfx::Size GetMinimumSize() OVERRIDE;
- virtual gfx::Size GetPreferredSize() OVERRIDE;
+ virtual gfx::Size GetMinimumSize() const OVERRIDE;
+ virtual gfx::Size GetPreferredSize() const OVERRIDE;
virtual bool OnKeyPressed(const ui::KeyEvent& event) OVERRIDE;
virtual bool OnMouseWheel(const ui::MouseWheelEvent& event) OVERRIDE;
diff --git a/chromium/ui/message_center/views/padded_button.cc b/chromium/ui/message_center/views/padded_button.cc
index 182cde698c9..add465b1720 100644
--- a/chromium/ui/message_center/views/padded_button.cc
+++ b/chromium/ui/message_center/views/padded_button.cc
@@ -50,7 +50,7 @@ void PaddedButton::SetPressedImage(int resource_id) {
resource_id));
}
-gfx::Size PaddedButton::GetPreferredSize() {
+gfx::Size PaddedButton::GetPreferredSize() const {
return gfx::Size(message_center::kControlButtonSize,
message_center::kControlButtonSize);
}
@@ -66,8 +66,6 @@ void PaddedButton::OnPaint(gfx::Canvas* canvas) {
if (!background_image_.isNull())
canvas->DrawImageInt(background_image_, position.x(), position.y());
canvas->DrawImageInt(image, position.x(), position.y());
- if (!overlay_image_.isNull())
- canvas->DrawImageInt(overlay_image_, position.x(), position.y());
}
views::Painter::PaintFocusPainter(this, canvas, focus_painter());
}
diff --git a/chromium/ui/message_center/views/padded_button.h b/chromium/ui/message_center/views/padded_button.h
index 04ae5c1d36b..c420621e9a1 100644
--- a/chromium/ui/message_center/views/padded_button.h
+++ b/chromium/ui/message_center/views/padded_button.h
@@ -24,7 +24,7 @@ class PaddedButton : public views::ImageButton {
virtual ~PaddedButton();
// Overridden from views::ImageButton:
- virtual gfx::Size GetPreferredSize() OVERRIDE;
+ virtual gfx::Size GetPreferredSize() const OVERRIDE;
virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE;
virtual void OnFocus() OVERRIDE;
@@ -49,4 +49,4 @@ class PaddedButton : public views::ImageButton {
} // namespace message_center
-#endif // UI_MESSAGE_CENTER_VIEWS_PADDED_BUTTON_H_ \ No newline at end of file
+#endif // UI_MESSAGE_CENTER_VIEWS_PADDED_BUTTON_H_
diff --git a/chromium/ui/message_center/views/proportional_image_view.cc b/chromium/ui/message_center/views/proportional_image_view.cc
index 1e52fa34cef..8ec9b32e6dc 100644
--- a/chromium/ui/message_center/views/proportional_image_view.cc
+++ b/chromium/ui/message_center/views/proportional_image_view.cc
@@ -9,55 +9,52 @@
namespace message_center {
-ProportionalImageView::ProportionalImageView(const gfx::ImageSkia& image)
- : image_(image) {
-}
+ProportionalImageView::ProportionalImageView(const gfx::ImageSkia& image,
+ const gfx::Size& max_size)
+ : image_(image), max_size_(max_size) {}
-ProportionalImageView::~ProportionalImageView() {
-}
+ProportionalImageView::~ProportionalImageView() {}
-gfx::Size ProportionalImageView::GetPreferredSize() {
- gfx::Insets insets = GetInsets();
- gfx::Rect rect = gfx::Rect(GetImageSizeForWidth(image_.width()));
- rect.Inset(-insets);
- return rect.size();
-}
+gfx::Size ProportionalImageView::GetPreferredSize() const { return max_size_; }
-int ProportionalImageView::GetHeightForWidth(int width) {
- // The border will count against the width available for the image
- // and towards the height taken by the image.
- gfx::Insets insets = GetInsets();
- int inset_width = width - insets.width();
- return GetImageSizeForWidth(inset_width).height() + insets.height();
+int ProportionalImageView::GetHeightForWidth(int width) const {
+ return max_size_.height();
}
void ProportionalImageView::OnPaint(gfx::Canvas* canvas) {
views::View::OnPaint(canvas);
- gfx::Size draw_size(GetImageSizeForWidth(width() - GetInsets().width()));
- if (!draw_size.IsEmpty()) {
- gfx::Rect draw_bounds = GetContentsBounds();
- draw_bounds.ClampToCenteredSize(draw_size);
-
- gfx::Size image_size(image_.size());
- if (image_size == draw_size) {
- canvas->DrawImageInt(image_, draw_bounds.x(), draw_bounds.y());
- } else {
- // Resize case
- SkPaint paint;
- paint.setFilterBitmap(true);
- canvas->DrawImageInt(image_, 0, 0,
- image_size.width(), image_size.height(),
- draw_bounds.x(), draw_bounds.y(),
- draw_size.width(), draw_size.height(),
- true, paint);
- }
+ gfx::Size draw_size = GetImageDrawingSize();
+
+ if (draw_size.IsEmpty())
+ return;
+
+ gfx::Rect draw_bounds = GetContentsBounds();
+ draw_bounds.ClampToCenteredSize(draw_size);
+
+ gfx::Size image_size(image_.size());
+
+ if (image_size == draw_size) {
+ canvas->DrawImageInt(image_, draw_bounds.x(), draw_bounds.y());
+ } else {
+ SkPaint paint;
+ paint.setFilterLevel(SkPaint::kLow_FilterLevel);
+
+ // This call resizes the image while drawing into the canvas.
+ canvas->DrawImageInt(
+ image_,
+ 0, 0, image_size.width(), image_size.height(),
+ draw_bounds.x(), draw_bounds.y(), draw_size.width(), draw_size.height(),
+ true,
+ paint);
}
}
-gfx::Size ProportionalImageView::GetImageSizeForWidth(int width) {
- gfx::Size size = visible() ? image_.size() : gfx::Size();
- return message_center::GetImageSizeForWidth(width, size);
+gfx::Size ProportionalImageView::GetImageDrawingSize() {
+ if (!visible())
+ return gfx::Size();
+ return message_center::GetImageSizeForContainerSize(
+ GetContentsBounds().size(), image_.size());
}
} // namespace message_center
diff --git a/chromium/ui/message_center/views/proportional_image_view.h b/chromium/ui/message_center/views/proportional_image_view.h
index 42f6dc2b346..7c1be9243c2 100644
--- a/chromium/ui/message_center/views/proportional_image_view.h
+++ b/chromium/ui/message_center/views/proportional_image_view.h
@@ -13,18 +13,19 @@ namespace message_center {
// ProportionalImageViews center their images to preserve their proportion.
class ProportionalImageView : public views::View {
public:
- ProportionalImageView(const gfx::ImageSkia& image);
+ ProportionalImageView(const gfx::ImageSkia& image, const gfx::Size& max_size);
virtual ~ProportionalImageView();
// Overridden from views::View:
- virtual gfx::Size GetPreferredSize() OVERRIDE;
- virtual int GetHeightForWidth(int width) OVERRIDE;
+ virtual gfx::Size GetPreferredSize() const OVERRIDE;
+ virtual int GetHeightForWidth(int width) const OVERRIDE;
virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE;
private:
- gfx::Size GetImageSizeForWidth(int width);
+ gfx::Size GetImageDrawingSize();
gfx::ImageSkia image_;
+ gfx::Size max_size_;
DISALLOW_COPY_AND_ASSIGN(ProportionalImageView);
};
diff --git a/chromium/ui/message_center/views/toast_contents_view.cc b/chromium/ui/message_center/views/toast_contents_view.cc
index 6c139343ba5..e5de6a25100 100644
--- a/chromium/ui/message_center/views/toast_contents_view.cc
+++ b/chromium/ui/message_center/views/toast_contents_view.cc
@@ -10,7 +10,7 @@
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
-#include "ui/base/accessibility/accessible_view_state.h"
+#include "ui/accessibility/ax_view_state.h"
#include "ui/gfx/animation/animation_delegate.h"
#include "ui/gfx/animation/slide_animation.h"
#include "ui/gfx/display.h"
@@ -24,10 +24,12 @@
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_delegate.h"
-#if defined(OS_WIN) && defined(USE_ASH)
+#if defined(OS_WIN)
#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
#endif
+using gfx::Screen;
+
namespace message_center {
namespace {
@@ -40,7 +42,7 @@ const int kFadeInOutDuration = 200;
} // namespace.
// static
-gfx::Size ToastContentsView::GetToastSizeForView(views::View* view) {
+gfx::Size ToastContentsView::GetToastSizeForView(const views::View* view) {
int width = kNotificationWidth + view->GetInsets().width();
return gfx::Size(width, view->GetHeightForWidth(width));
}
@@ -84,7 +86,16 @@ void ToastContentsView::SetContents(MessageView* view,
// The notification type should be ALERT, otherwise the accessibility message
// won't be read for this view which returns ROLE_WINDOW.
if (already_has_contents && a11y_feedback_for_updates)
- NotifyAccessibilityEvent(ui::AccessibilityTypes::EVENT_ALERT, false);
+ NotifyAccessibilityEvent(ui::AX_EVENT_ALERT, false);
+}
+
+void ToastContentsView::UpdateContents(const Notification& notification,
+ bool a11y_feedback_for_updates) {
+ DCHECK_GT(child_count(), 0);
+ MessageView* message_view = static_cast<MessageView*>(child_at(0));
+ message_view->UpdateWithNotification(notification);
+ if (a11y_feedback_for_updates)
+ NotifyAccessibilityEvent(ui::AX_EVENT_ALERT, false);
}
void ToastContentsView::RevealWithAnimation(gfx::Point origin) {
@@ -152,7 +163,7 @@ void ToastContentsView::StartFadeIn() {
fade_animation_->Stop();
GetWidget()->SetOpacity(0);
- GetWidget()->Show();
+ GetWidget()->ShowInactive();
fade_animation_->Reset(0);
fade_animation_->Show();
}
@@ -172,16 +183,16 @@ void ToastContentsView::OnBoundsAnimationEndedOrCancelled(
const gfx::Animation* animation) {
if (is_closing_ && closing_animation_ == animation && GetWidget()) {
views::Widget* widget = GetWidget();
-#if defined(USE_AURA)
+
// TODO(dewittj): This is a workaround to prevent a nasty bug where
// closing a transparent widget doesn't actually remove the window,
// causing entire areas of the screen to become unresponsive to clicks.
// See crbug.com/243469
widget->Hide();
-# if defined(OS_WIN)
+#if defined(OS_WIN)
widget->SetOpacity(0xFF);
-# endif
#endif
+
widget->Close();
}
@@ -225,14 +236,6 @@ void ToastContentsView::WindowClosing() {
collection_->ForgetToast(this);
}
-bool ToastContentsView::CanActivate() const {
-#if defined(OS_WIN) && defined(USE_AURA)
- return true;
-#else
- return false;
-#endif
-}
-
void ToastContentsView::OnDisplayChanged() {
views::Widget* widget = GetWidget();
if (!widget)
@@ -242,8 +245,10 @@ void ToastContentsView::OnDisplayChanged() {
if (!native_view || !collection_.get())
return;
- collection_->OnDisplayBoundsChanged(gfx::Screen::GetScreenFor(
- native_view)->GetDisplayNearestWindow(native_view));
+ collection_->OnDisplayMetricsChanged(
+ Screen::GetScreenFor(native_view)->GetDisplayNearestWindow(native_view),
+ gfx::DisplayObserver::DISPLAY_METRIC_BOUNDS |
+ gfx::DisplayObserver::DISPLAY_METRIC_WORK_AREA);
}
void ToastContentsView::OnWorkAreaChanged() {
@@ -255,8 +260,9 @@ void ToastContentsView::OnWorkAreaChanged() {
if (!native_view || !collection_.get())
return;
- collection_->OnDisplayBoundsChanged(gfx::Screen::GetScreenFor(
- native_view)->GetDisplayNearestWindow(native_view));
+ collection_->OnDisplayMetricsChanged(
+ Screen::GetScreenFor(native_view)->GetDisplayNearestWindow(native_view),
+ gfx::DisplayObserver::DISPLAY_METRIC_WORK_AREA);
}
// views::View
@@ -277,14 +283,14 @@ void ToastContentsView::Layout() {
}
}
-gfx::Size ToastContentsView::GetPreferredSize() {
+gfx::Size ToastContentsView::GetPreferredSize() const {
return child_count() ? GetToastSizeForView(child_at(0)) : gfx::Size();
}
-void ToastContentsView::GetAccessibleState(ui::AccessibleViewState* state) {
+void ToastContentsView::GetAccessibleState(ui::AXViewState* state) {
if (child_count() > 0)
child_at(0)->GetAccessibleState(state);
- state->role = ui::AccessibilityTypes::ROLE_WINDOW;
+ state->role = ui::AX_ROLE_WINDOW;
}
void ToastContentsView::ClickOnNotification(
@@ -300,15 +306,13 @@ void ToastContentsView::RemoveNotification(
collection_->RemoveNotification(notification_id, by_user);
}
-void ToastContentsView::DisableNotificationsFromThisSource(
- const NotifierId& notifier_id) {
- if (collection_)
- collection_->DisableNotificationsFromThisSource(notifier_id);
-}
-
-void ToastContentsView::ShowNotifierSettingsBubble() {
- if (collection_)
- collection_->ShowNotifierSettingsBubble();
+scoped_ptr<ui::MenuModel> ToastContentsView::CreateMenuModel(
+ const NotifierId& notifier_id,
+ const base::string16& display_source) {
+ // Should not reach, the context menu should be handled in
+ // MessagePopupCollection.
+ NOTREACHED();
+ return scoped_ptr<ui::MenuModel>();
}
bool ToastContentsView::HasClickedListener(
@@ -325,43 +329,17 @@ void ToastContentsView::ClickOnNotificationButton(
collection_->ClickOnNotificationButton(notification_id, button_index);
}
-void ToastContentsView::ExpandNotification(
- const std::string& notification_id) {
- if (collection_)
- collection_->ExpandNotification(notification_id);
-}
-
-void ToastContentsView::GroupBodyClicked(
- const std::string& last_notification_id) {
- // No group views in popup collection.
- NOTREACHED();
-}
-
-// When clicked on the "N more" button, perform some reasonable action.
-// TODO(dimich): find out what the reasonable action could be.
-void ToastContentsView::ExpandGroup(const NotifierId& notifier_id) {
- // No group views in popup collection.
- NOTREACHED();
-}
-
-void ToastContentsView::RemoveGroup(const NotifierId& notifier_id) {
- // No group views in popup collection.
- NOTREACHED();
-}
-
void ToastContentsView::CreateWidget(gfx::NativeView parent) {
views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP);
params.keep_on_top = true;
if (parent)
params.parent = parent;
- else
- params.top_level = true;
params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
params.delegate = this;
views::Widget* widget = new views::Widget();
widget->set_focus_on_creation(false);
-#if defined(OS_WIN) && defined(USE_ASH)
+#if defined(OS_WIN)
// We want to ensure that this toast always goes to the native desktop,
// not the Ash desktop (since there is already another toast contents view
// there.
diff --git a/chromium/ui/message_center/views/toast_contents_view.h b/chromium/ui/message_center/views/toast_contents_view.h
index 3a609ca99a6..1b39d81d6f4 100644
--- a/chromium/ui/message_center/views/toast_contents_view.h
+++ b/chromium/ui/message_center/views/toast_contents_view.h
@@ -39,7 +39,7 @@ class ToastContentsView : public views::WidgetDelegateView,
public gfx::AnimationDelegate {
public:
// Computes the size of a toast assuming it will host the given view.
- static gfx::Size GetToastSizeForView(views::View* view);
+ static gfx::Size GetToastSizeForView(const views::View* view);
ToastContentsView(const std::string& notification_id,
base::WeakPtr<MessagePopupCollection> collection);
@@ -50,6 +50,9 @@ class ToastContentsView : public views::WidgetDelegateView,
// accessibility message should be read after this update.
void SetContents(MessageView* view, bool a11y_feedback_for_updates);
+ void UpdateContents(const Notification& notification,
+ bool a11y_feedback_for_updates);
+
// Shows the new toast for the first time, animated.
// |origin| is the right-bottom corner of the toast.
void RevealWithAnimation(gfx::Point origin);
@@ -71,25 +74,20 @@ class ToastContentsView : public views::WidgetDelegateView,
virtual void OnMouseEntered(const ui::MouseEvent& event) OVERRIDE;
virtual void OnMouseExited(const ui::MouseEvent& event) OVERRIDE;
virtual void Layout() OVERRIDE;
- virtual gfx::Size GetPreferredSize() OVERRIDE;
- virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE;
+ virtual gfx::Size GetPreferredSize() const OVERRIDE;
+ virtual void GetAccessibleState(ui::AXViewState* state) OVERRIDE;
private:
// Overridden from MessageCenterController:
virtual void ClickOnNotification(const std::string& notification_id) OVERRIDE;
virtual void RemoveNotification(const std::string& notification_id,
bool by_user) OVERRIDE;
- virtual void DisableNotificationsFromThisSource(
- const NotifierId& notifier_id) OVERRIDE;
- virtual void ShowNotifierSettingsBubble() OVERRIDE;
+ virtual scoped_ptr<ui::MenuModel> CreateMenuModel(
+ const NotifierId& notifier_id,
+ const base::string16& display_source) OVERRIDE;
virtual bool HasClickedListener(const std::string& notification_id) OVERRIDE;
virtual void ClickOnNotificationButton(const std::string& notification_id,
int button_index) OVERRIDE;
- virtual void ExpandNotification(const std::string& notification_id) OVERRIDE;
- virtual void GroupBodyClicked(const std::string& last_notification_id)
- OVERRIDE;
- virtual void ExpandGroup(const NotifierId& notifier_id) OVERRIDE;
- virtual void RemoveGroup(const NotifierId& notifier_id) OVERRIDE;
// Overridden from gfx::AnimationDelegate:
virtual void AnimationProgressed(const gfx::Animation* animation) OVERRIDE;
@@ -99,7 +97,6 @@ class ToastContentsView : public views::WidgetDelegateView,
// Overridden from views::WidgetDelegate:
virtual views::View* GetContentsView() OVERRIDE;
virtual void WindowClosing() OVERRIDE;
- virtual bool CanActivate() const OVERRIDE;
virtual void OnDisplayChanged() OVERRIDE;
virtual void OnWorkAreaChanged() OVERRIDE;