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