1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "ui/message_center/views/message_center_bubble.h"
6
7#include "ui/base/l10n/l10n_util.h"
8#include "ui/message_center/message_center_style.h"
9#include "ui/message_center/views/message_center_view.h"
10#include "ui/strings/grit/ui_strings.h"
11#include "ui/views/layout/fill_layout.h"
12#include "ui/views/widget/widget.h"
13
14namespace message_center {
15
16// ContentsView ////////////////////////////////////////////////////////////////
17
18// Handles changes in MessageCenterView sizes.
19class ContentsView : public views::View {
20 public:
21  explicit ContentsView(MessageCenterBubble* bubble, views::View* contents);
22  virtual ~ContentsView();
23
24  // Overridden from views::View:
25  virtual int GetHeightForWidth(int width) const OVERRIDE;
26
27 protected:
28  // Overridden from views::View:
29  virtual void ChildPreferredSizeChanged(View* child) OVERRIDE;
30
31 private:
32  base::WeakPtr<MessageCenterBubble> bubble_;
33
34  DISALLOW_COPY_AND_ASSIGN(ContentsView);
35};
36
37ContentsView::ContentsView(MessageCenterBubble* bubble, views::View* contents)
38    : bubble_(bubble->AsWeakPtr()) {
39  SetLayoutManager(new views::FillLayout());
40  AddChildView(contents);
41}
42
43ContentsView::~ContentsView() {
44}
45
46int ContentsView::GetHeightForWidth(int width) const {
47  DCHECK_EQ(1, child_count());
48  int contents_width = std::max(width - GetInsets().width(), 0);
49  int contents_height = child_at(0)->GetHeightForWidth(contents_width);
50  return contents_height + GetInsets().height();
51}
52
53void ContentsView::ChildPreferredSizeChanged(View* child) {
54  // TODO(dharcourt): Reduce the amount of updating this requires.
55  if (bubble_.get())
56    bubble_->bubble_view()->UpdateBubble();
57}
58
59// MessageCenterBubble /////////////////////////////////////////////////////////
60
61MessageCenterBubble::MessageCenterBubble(MessageCenter* message_center,
62                                         MessageCenterTray* tray,
63                                         bool first_item_has_no_margin)
64    : MessageBubbleBase(message_center, tray),
65      message_center_view_(NULL),
66      initially_settings_visible_(false),
67      first_item_has_no_margin_(first_item_has_no_margin),
68      title_(l10n_util::GetStringUTF16(IDS_MESSAGE_CENTER_FOOTER_TITLE)) {
69}
70
71MessageCenterBubble::~MessageCenterBubble() {
72}
73
74void MessageCenterBubble::SetSettingsVisible() {
75  if (message_center_view_)
76    message_center_view_->SetSettingsVisible(true);
77  else
78    initially_settings_visible_ = true;
79}
80
81views::TrayBubbleView::InitParams MessageCenterBubble::GetInitParams(
82    views::TrayBubbleView::AnchorAlignment anchor_alignment) {
83  views::TrayBubbleView::InitParams init_params =
84      GetDefaultInitParams(anchor_alignment);
85  init_params.min_width += kMarginBetweenItems * 2;
86  init_params.max_width += kMarginBetweenItems * 2;
87  init_params.max_height = max_height();
88  init_params.can_activate = true;
89  init_params.first_item_has_no_margin = first_item_has_no_margin_;
90  return init_params;
91}
92
93void MessageCenterBubble::InitializeContents(
94    views::TrayBubbleView* new_bubble_view) {
95  set_bubble_view(new_bubble_view);
96  bubble_view()->GetWidget()->AddObserver(this);
97  message_center_view_ = new MessageCenterView(
98      message_center(),
99      tray(),
100      max_height(),
101      initially_settings_visible_,
102      false, /* MessageCenterBubble should be used only on ChromeOS.
103              Message center is never shown top down in ChromeOS. */
104      title_);
105  bubble_view()->AddChildView(new ContentsView(this, message_center_view_));
106  // Resize the content of the bubble view to the given bubble size. This is
107  // necessary in case of the bubble border forcing a bigger size then the
108  // |new_bubble_view| actually wants. See crbug.com/169390.
109  bubble_view()->Layout();
110  UpdateBubbleView();
111}
112
113void MessageCenterBubble::OnBubbleViewDestroyed() {
114  message_center_view_ = NULL;
115}
116
117void MessageCenterBubble::UpdateBubbleView() {
118  if (!bubble_view())
119    return;  // Could get called after view is closed
120  const NotificationList::Notifications& notifications =
121      message_center()->GetVisibleNotifications();
122  message_center_view_->SetNotifications(notifications);
123  bubble_view()->GetWidget()->Show();
124  bubble_view()->UpdateBubble();
125}
126
127void MessageCenterBubble::OnWidgetClosing(views::Widget* widget) {
128  bubble_view()->GetWidget()->RemoveObserver(this);
129  if (message_center_view_)
130    message_center_view_->SetIsClosing(true);
131}
132
133void MessageCenterBubble::OnMouseEnteredView() {
134}
135
136void MessageCenterBubble::OnMouseExitedView() {
137}
138
139size_t MessageCenterBubble::NumMessageViewsForTest() const {
140  return message_center_view_->NumMessageViewsForTest();
141}
142
143}  // namespace message_center
144