Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(334)

Side by Side Diff: chrome/browser/ui/views/message_center/message_center_tray_host_win.cc

Issue 11819048: Implement message center on Windows (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Rebase on master @fa1d2262 and rearrange dependencies. Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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 "chrome/browser/ui/views/message_center/message_center_tray_host_win.h"
6
7 #include "base/memory/singleton.h"
8 #include "base/utf_string_conversions.h"
9 #include "chrome/browser/browser_process.h"
10 #include "chrome/browser/status_icons/status_icon.h"
11 #include "chrome/browser/status_icons/status_tray.h"
12 #include "chrome/browser/ui/message_center/message_center_util.h"
13 #include "grit/theme_resources.h"
14 #include "ui/base/resource/resource_bundle.h"
15 #include "ui/base/win/hwnd_util.h"
16 #include "ui/gfx/image/image_skia_operations.h"
17 #include "ui/gfx/screen.h"
18 #include "ui/message_center/message_center_tray.h"
19
20 namespace {
21
22 // Tray constants
23 const int kPaddingFromLeftEdgeOfSystemTrayBottomAlignment = 8;
24
25 gfx::Rect GetCornerAnchorRect() {
26 gfx::Screen* screen = gfx::Screen::GetNativeScreen();
27 gfx::Point cursor = screen->GetCursorScreenPoint();
28 gfx::Rect rect = screen->GetPrimaryDisplay().work_area();
29 rect.Inset(kPaddingFromLeftEdgeOfSystemTrayBottomAlignment, 0);
30 return gfx::Rect(rect.bottom_right(), gfx::Size());
31 }
32
33 // GetMouseAnchorRect returns a rectangle that is near the cursor point, but
34 // whose behavior depends on where the Windows taskbar is. If it is on the
35 // top or bottom of the screen, we want the arrow to touch the edge of the
36 // taskbar directly above or below the mouse pointer and within the work area.
37 // Otherwise, position the anchor on the mouse cursor directly.
38 gfx::Rect GetMouseAnchorRect() {
39 gfx::Screen* screen = gfx::Screen::GetNativeScreen();
40 gfx::Point cursor = screen->GetCursorScreenPoint();
41 gfx::Rect rect = screen->GetPrimaryDisplay().bounds();
42 gfx::Rect work_area = screen->GetPrimaryDisplay().work_area();
43
44 // Inset the rectangle by the taskbar width if it is on top or bottom.
45 rect.set_y(work_area.y());
46 rect.set_height(work_area.height());
47
48 rect.Inset(kPaddingFromLeftEdgeOfSystemTrayBottomAlignment, 0);
49
50 // Want to find a mouse point that is on the mouse cursor, unless the mouse is
51 // over the start menu and the start menu is on the top or bottom.
52 gfx::Rect mouse_anchor_rect(gfx::BoundingRect(cursor, rect.bottom_right()));
53 mouse_anchor_rect.set_height(0);
54 if (!rect.Contains(cursor))
55 mouse_anchor_rect.AdjustToFit(rect);
56 mouse_anchor_rect.set_width(0);
57 return mouse_anchor_rect;
58 }
59
60 } // namespace
61
62 #if defined(ENABLE_MESSAGE_CENTER)
63
64 namespace chrome {
65
66 // static
67 ui::MessageCenterTrayHost* GetMessageCenterTray() {
68 return ui::MessageCenterTrayHostWin::GetInstance();
69 }
70
71 } // namespace chrome
72
73 #endif
74
75
76 namespace ui {
77
78 // TODO(dewittj): Un-singleton.
79 MessageCenterTrayHostWin* MessageCenterTrayHostWin::GetInstance() {
80 return Singleton<MessageCenterTrayHostWin>::get();
81 }
82
83 MessageCenterTrayHostWin::MessageCenterTrayHostWin()
84 : status_icon_(NULL),
85 message_center_visible_(false) {
86 message_center_tray_ = new MessageCenterTray(this);
87 }
88
89 MessageCenterTrayHostWin::~MessageCenterTrayHostWin() {
90 if (status_icon_ != NULL) {
91 status_icon_->RemoveObserver(this);
92 StatusTray * status_tray = g_browser_process->status_tray();
93 status_tray->RemoveStatusIcon(status_icon_);
94 status_icon_ = NULL;
95 }
96 }
97
98 message_center::MessageCenter* MessageCenterTrayHostWin::message_center() {
99 return message_center_tray_->message_center();
100 }
101
102 void MessageCenterTrayHostWin::OnMessageCenterTrayChanged() {
103 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
104 bool has_notifications = message_center()->NotificationCount() > 0;
105 StatusTray* status_tray = g_browser_process->status_tray();
106 if (has_notifications) {
107 if (status_icon_ == NULL) {
108 status_icon_ = status_tray->CreateStatusIcon();
109 status_icon_->AddObserver(this);
110 }
111 // TODO(dewittj): Get some icons.
112 gfx::ImageSkia* icon =
113 rb.GetImageSkiaNamed(IDR_ALLOWED_NOTIFICATION);
114 if (message_center()->UnreadNotificationCount() > 0) {
115 status_icon_->SetImage(*icon);
116 } else {
117 status_icon_->SetImage(
118 gfx::ImageSkiaOperations::CreateTransparentImage(*icon, .5));
119 }
120 } else if (status_icon_ != NULL) {
121 status_tray->RemoveStatusIcon(status_icon_);
122 status_icon_ = NULL;
123 }
124 }
125
126 string16 MessageCenterTrayHostWin::GetAccessibleNameForBubble() {
127 // TODO(dewittj): Get a proper string resource.
128 return ASCIIToUTF16("Windows Notification Center");
129 }
130
131 void MessageCenterTrayHostWin::OnShowMessageCenterBubble() {
132 message_center_visible_ = true;
133 }
134
135 void MessageCenterTrayHostWin::OnHideMessageCenterBubble() {
136 message_center_visible_ = false;
137 }
138
139 gfx::Rect MessageCenterTrayHostWin::GetAnchorRect(
140 views::Widget* anchor_widget,
141 views::TrayBubbleView::AnchorType anchor_type,
142 views::TrayBubbleView::AnchorAlignment anchor_alignment) {
143 // |message_center_visible_| is set before the bubble is actually rendered,
144 // so the flag can be used to determine which anchor to use.
145 if (message_center_visible_)
146 return message_center_anchor_rect_;
147 return GetCornerAnchorRect();
148 }
149
150 bool MessageCenterTrayHostWin::CanShowPopups() {
151 // TODO(dewittj): This will eventually depend on whether quiet mode is active.
152 return true;
153 }
154
155 void MessageCenterTrayHostWin::OnStatusIconClicked() {
156 UpdateAnchorRect();
157 message_center_tray_->ToggleMessageCenterBubble();
158 }
159
160 void MessageCenterTrayHostWin::UpdateAnchorRect() {
161 message_center_anchor_rect_ = GetMouseAnchorRect();
162 }
163
164 views::TrayBubbleView::AnchorAlignment
165 MessageCenterTrayHostWin::GetAnchorAlignment() {
166 gfx::Screen* screen = gfx::Screen::GetNativeScreen();
167 // TODO(dewittj): It's possible GetPrimaryDisplay is wrong.
168 gfx::Rect screen_bounds = screen->GetPrimaryDisplay().bounds();
169 gfx::Rect work_area = screen->GetPrimaryDisplay().work_area();
170
171 if (work_area.height() < screen_bounds.height())
172 return views::TrayBubbleView::ANCHOR_ALIGNMENT_BOTTOM;
173 if (work_area.x() > screen_bounds.x())
174 return views::TrayBubbleView::ANCHOR_ALIGNMENT_LEFT;
175 return views::TrayBubbleView::ANCHOR_ALIGNMENT_RIGHT;
176 }
177
178 void MessageCenterTrayHostWin::UpdateInitParams(
179 views::TrayBubbleView::InitParams* init_params) {
180 init_params->anchor_type = views::TrayBubbleView::ANCHOR_TYPE_TRAY;
181 init_params->arrow_alignment = views::BubbleBorder::ALIGN_ARROW_TO_MID_ANCHOR;
182 // TODO(dewittj): Show big shadow without blocking clicks.
183 init_params->shadow = views::BubbleBorder::NO_SHADOW;
184 }
185
186 gfx::NativeView MessageCenterTrayHostWin::GetBubbleWindowContainer() {
187 return NULL;
188 }
189
190 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698