Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / ui / views / message_center / message_center_widget_delegate.cc
blob16b3eff39262f73c761f6622392c67fa0be39faa
1 // Copyright 2013 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.
5 #include "chrome/browser/ui/views/message_center/message_center_widget_delegate.h"
7 #include <complex>
9 #include "chrome/browser/ui/views/message_center/message_center_frame_view.h"
10 #include "content/public/browser/user_metrics.h"
11 #include "ui/base/accessibility/accessible_view_state.h"
12 #include "ui/gfx/screen.h"
13 #include "ui/message_center/message_center_style.h"
14 #include "ui/message_center/message_center_util.h"
15 #include "ui/message_center/views/message_center_view.h"
16 #include "ui/native_theme/native_theme.h"
17 #include "ui/views/border.h"
18 #include "ui/views/layout/box_layout.h"
19 #include "ui/views/widget/widget.h"
21 #if defined(OS_WIN)
22 #include "ui/views/win/hwnd_util.h"
23 #endif
25 #if defined(USE_ASH)
26 #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
27 #endif
29 namespace message_center {
31 MessageCenterWidgetDelegate::MessageCenterWidgetDelegate(
32 WebNotificationTray* tray,
33 MessageCenterTray* mc_tray,
34 bool initially_settings_visible,
35 const PositionInfo& pos_info)
36 : MessageCenterView(tray->message_center(),
37 mc_tray,
38 pos_info.max_height,
39 initially_settings_visible,
40 pos_info.message_center_alignment &
41 ALIGNMENT_TOP), // Show buttons on top if message
42 // center is top aligned
43 pos_info_(pos_info),
44 tray_(tray) {
45 // A WidgetDelegate should be deleted on DeleteDelegate.
46 set_owned_by_client();
48 views::BoxLayout* layout =
49 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0);
50 layout->set_spread_blank_space(true);
51 SetLayoutManager(layout);
53 AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE));
55 if (get_use_acceleration_when_possible()) {
56 SetPaintToLayer(true);
57 SetFillsBoundsOpaquely(true);
60 InitWidget();
63 MessageCenterWidgetDelegate::~MessageCenterWidgetDelegate() {
64 views::Widget* widget = GetWidget();
65 if (widget) {
66 widget->RemoveObserver(this);
70 views::View* MessageCenterWidgetDelegate::GetContentsView() {
71 return this;
74 views::NonClientFrameView*
75 MessageCenterWidgetDelegate::CreateNonClientFrameView(views::Widget* widget) {
76 MessageCenterFrameView* frame_view = new MessageCenterFrameView();
77 border_insets_ = frame_view->GetInsets();
78 return frame_view;
81 void MessageCenterWidgetDelegate::DeleteDelegate() {
82 delete this;
85 views::Widget* MessageCenterWidgetDelegate::GetWidget() {
86 return View::GetWidget();
89 const views::Widget* MessageCenterWidgetDelegate::GetWidget() const {
90 return View::GetWidget();
93 void MessageCenterWidgetDelegate::OnWidgetActivationChanged(
94 views::Widget* widget,
95 bool active) {
96 if (!active) {
97 tray_->SendHideMessageCenter();
101 void MessageCenterWidgetDelegate::OnWidgetClosing(views::Widget* widget) {
102 SetIsClosing(true);
103 tray_->MarkMessageCenterHidden();
106 void MessageCenterWidgetDelegate::PreferredSizeChanged() {
107 GetWidget()->SetBounds(GetMessageCenterBounds());
108 views::View::PreferredSizeChanged();
111 gfx::Size MessageCenterWidgetDelegate::GetPreferredSize() {
112 int preferred_width = kNotificationWidth + 2 * kMarginBetweenItems;
113 return gfx::Size(preferred_width, GetHeightForWidth(preferred_width));
116 gfx::Size MessageCenterWidgetDelegate::GetMaximumSize() {
117 gfx::Size size = GetPreferredSize();
118 return size;
121 int MessageCenterWidgetDelegate::GetHeightForWidth(int width) {
122 int height = MessageCenterView::GetHeightForWidth(width);
123 return (pos_info_.max_height != 0) ?
124 std::min(height, pos_info_.max_height - border_insets_.height()) : height;
127 bool MessageCenterWidgetDelegate::AcceleratorPressed(
128 const ui::Accelerator& accelerator) {
129 if (accelerator.key_code() != ui::VKEY_ESCAPE)
130 return false;
131 tray_->SendHideMessageCenter();
132 return true;
135 void MessageCenterWidgetDelegate::InitWidget() {
136 views::Widget* widget = new views::Widget();
137 views::Widget::InitParams params(views::Widget::InitParams::TYPE_BUBBLE);
138 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
139 params.delegate = this;
140 params.keep_on_top = true;
141 params.top_level = true;
142 #if defined(USE_ASH)
143 // This class is not used in Ash; there is another container for the message
144 // center that's used there. So, we must be in a Views + Ash environment. We
145 // want the notification center to be available on both desktops. Setting the
146 // |native_widget| variable here ensures that the widget is hosted on the
147 // native desktop.
148 params.native_widget = new views::DesktopNativeWidgetAura(widget);
149 #endif
150 widget->Init(params);
152 widget->AddObserver(this);
153 widget->StackAtTop();
154 widget->SetAlwaysOnTop(true);
156 const NotificationList::Notifications& notifications =
157 tray_->message_center()->GetVisibleNotifications();
158 SetNotifications(notifications);
160 widget->SetBounds(GetMessageCenterBounds());
161 widget->Show();
162 widget->Activate();
165 gfx::Point MessageCenterWidgetDelegate::GetCorrectedAnchor(
166 gfx::Size calculated_size) {
167 gfx::Point corrected_anchor = pos_info_.inital_anchor_point;
169 // Inset the width slightly so that the click point is not exactly on the edge
170 // of the message center but somewhere within the middle 60 %.
171 int insetted_width = (calculated_size.width() * 4) / 5;
173 if (pos_info_.taskbar_alignment == ALIGNMENT_TOP ||
174 pos_info_.taskbar_alignment == ALIGNMENT_BOTTOM) {
175 int click_point_x = tray_->mouse_click_point().x();
177 if (pos_info_.message_center_alignment & ALIGNMENT_RIGHT) {
178 int opposite_x_corner =
179 pos_info_.inital_anchor_point.x() - insetted_width;
181 // If the click point is outside the x axis length of the message center,
182 // push the message center towards the left to align with the click point.
183 if (opposite_x_corner > click_point_x)
184 corrected_anchor.set_x(pos_info_.inital_anchor_point.x() -
185 (opposite_x_corner - click_point_x));
186 } else {
187 int opposite_x_corner =
188 pos_info_.inital_anchor_point.x() + insetted_width;
190 if (opposite_x_corner < click_point_x)
191 corrected_anchor.set_x(pos_info_.inital_anchor_point.x() +
192 (click_point_x - opposite_x_corner));
194 } else if (pos_info_.taskbar_alignment == ALIGNMENT_LEFT ||
195 pos_info_.taskbar_alignment == ALIGNMENT_RIGHT) {
196 int click_point_y = tray_->mouse_click_point().y();
198 if (pos_info_.message_center_alignment & ALIGNMENT_BOTTOM) {
199 int opposite_y_corner =
200 pos_info_.inital_anchor_point.y() - insetted_width;
202 // If the click point is outside the y axis length of the message center,
203 // push the message center upwards to align with the click point.
204 if (opposite_y_corner > click_point_y)
205 corrected_anchor.set_y(pos_info_.inital_anchor_point.y() -
206 (opposite_y_corner - click_point_y));
207 } else {
208 int opposite_y_corner =
209 pos_info_.inital_anchor_point.y() + insetted_width;
211 if (opposite_y_corner < click_point_y)
212 corrected_anchor.set_y(pos_info_.inital_anchor_point.y() +
213 (click_point_y - opposite_y_corner));
216 return corrected_anchor;
219 gfx::Rect MessageCenterWidgetDelegate::GetMessageCenterBounds() {
220 gfx::Size size = GetPreferredSize();
222 // Make space for borders on sides.
223 size.Enlarge(border_insets_.width(), border_insets_.height());
224 gfx::Rect bounds(size);
226 gfx::Point corrected_anchor = GetCorrectedAnchor(size);
228 if (pos_info_.message_center_alignment & ALIGNMENT_TOP)
229 bounds.set_y(corrected_anchor.y());
230 if (pos_info_.message_center_alignment & ALIGNMENT_BOTTOM)
231 bounds.set_y(corrected_anchor.y() - size.height());
232 if (pos_info_.message_center_alignment & ALIGNMENT_LEFT)
233 bounds.set_x(corrected_anchor.x());
234 if (pos_info_.message_center_alignment & ALIGNMENT_RIGHT)
235 bounds.set_x(corrected_anchor.x() - size.width());
237 return bounds;
240 } // namespace message_center