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

Side by Side Diff: chrome/browser/notifications/balloon_win.cc

Issue 208068: Desktop Notifications UI (for windows) (Closed)
Patch Set: Created 11 years, 3 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) 2009 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/notifications/balloons.h"
6
7 #include "base/logging.h"
8 #include "base/gfx/rect.h"
9 #include "chrome/browser/notifications/balloon_view_win.h"
10 #include "chrome/browser/renderer_host/render_view_host.h"
11 #include "chrome/browser/renderer_host/render_widget_host_view_win.h"
12 #include "chrome/browser/renderer_host/site_instance.h"
13 #include "views/window/window_win.h"
14
15 namespace {
16 // Portion of the screen allotted for notifications.
17 // When notification balloons extend over this threshold, no new notifications
18 // are shown until some balloons are expired/closed.
19 const double kPercentBalloonFillFactor = 0.7;
20
21 // Allow at least this number of balloons on the screen.
22 const int kMinAllowedBalloonCount = 2;
23
24 void GetMainScreenWorkArea(gfx::Rect* bounds) {
25 DCHECK(bounds);
26 RECT work_area = {0};
27 if (::SystemParametersInfo(SPI_GETWORKAREA, 0, &work_area, 0)) {
28 bounds->SetRect(work_area.left,
29 work_area.top,
30 work_area.right,
31 work_area.bottom);
32 } else {
33 // If failed to call SystemParametersInfo for some reason, we simply get the
34 // full screen size as an alternative.
35 bounds->SetRect(0,
36 0,
37 ::GetSystemMetrics(SM_CXSCREEN) - 1,
38 ::GetSystemMetrics(SM_CYSCREEN) - 1);
39 }
40 }
41
42 double GetSystemFontScaleFactor() {
43 return 1.0;
44 }
45 } // namespace
46
47 BalloonCollection::BalloonCollection() {
48 }
49
50 void BalloonCollection::AddObserver(BalloonCollectionObserver* observer) {
51 DCHECK(observer);
52 observers_.push_back(observer);
53 observer->OnBalloonSpaceChanged();
54 }
55
56 bool BalloonCollection::HasSpace() const {
57 if (count() < kMinAllowedBalloonCount) {
58 return true;
59 }
60
61 int max_balloon_length = 0;
62 int total_length = 0;
63 layout_.GetMaxLengths(&max_balloon_length, &total_length);
64
65 int current_max_length = max_balloon_length * count();
66 int max_allowed_length = static_cast<int>(total_length *
67 kPercentBalloonFillFactor);
68 return current_max_length < max_allowed_length - max_balloon_length;
69 }
70
71 void BalloonCollection::Add(const Notification& notification,
72 Profile* profile,
73 SiteInstance* site_instance) {
74 Balloon* new_balloon = MakeBalloon(notification, profile, site_instance);
75 gfx::Size size(layout_.min_balloon_width(), layout_.min_balloon_height());
76 new_balloon->SetSize(size);
77 balloons_.push_back(new_balloon);
78 gfx::Point origin = layout_.GetOrigin();
79 for (Balloons::iterator it = balloons_.begin(); it != balloons_.end(); ++it) {
80 gfx::Point upper_left = layout_.NextPosition((*it)->size(), &origin);
81 (*it)->SetPosition(upper_left, false);
82 }
83 new_balloon->Show();
84 notification.display();
85 for (BalloonObservers::iterator it = observers_.begin();
86 it != observers_.end();
87 ++it) {
88 (*it)->OnBalloonSpaceChanged();
89 }
90 }
91
92 void BalloonCollection::OnBalloonClosed(Balloon* source) {
93 source->notification().close(true);
94
95 for (Balloons::iterator it = balloons_.begin(); it != balloons_.end(); ++it) {
96 if (*it == source) {
97 balloons_.erase(it);
98 break;
99 }
100 }
101
102 gfx::Point origin = layout_.GetOrigin();
103 for (Balloons::iterator it = balloons_.begin(); it != balloons_.end(); ++it) {
104 gfx::Point upper_left = layout_.NextPosition((*it)->size(), &origin);
105 (*it)->SetPosition(upper_left, true);
106 }
107 }
108
109 void BalloonCollection::ShowAll() {
110 }
111
112 void BalloonCollection::HideAll() {
113 }
114
115 Balloon::Balloon(const Notification& notification,
116 Profile* profile,
117 SiteInstance* site_instance,
118 BalloonCloseListener* listener)
119 : profile_(profile),
120 site_instance_(site_instance),
121 notification_(notification),
122 close_listener_(listener) {
123 }
124
125 Balloon::~Balloon() {
126 }
127
128 void Balloon::Show() {
129 if (!balloon_view_.get()) {
130 balloon_view_.reset(new BalloonView());
131 balloon_view_->Show(this);
132 }
133 }
134
135
136 void Balloon::Close() {
137 if (close_listener_) {
138 close_listener_->OnBalloonClosed(this);
139 }
140 }
141
142 void Balloon::SetPosition(const gfx::Point& upper_left, bool reposition) {
143 position_ = upper_left;
144 if (reposition && balloon_view_.get()) {
145 balloon_view_->RepositionToBalloon();
146 }
147 }
148
149 void Balloon::SetSize(const gfx::Size& size) {
150 size_ = size;
151 }
152
153 const gfx::Point& Balloon::position() const {
154 return position_;
155 }
156
157 const gfx::Size& Balloon::size() const {
158 return size_;
159 }
160
161 BalloonCollection::Layout::Placement BalloonCollection::Layout::placement_ =
162 BalloonCollection::Layout::VERTICALLY_FROM_BOTTOM_RIGHT;
163
164 BalloonCollection::Layout::Layout()
165 : font_scale_factor_(1.0) {
166 RefreshSystemMetrics();
167 }
168
169 // Scale the size to count in the system font factor
170 int BalloonCollection::Layout::ScaleSize(int size) const {
171 return static_cast<int>(size * font_scale_factor_);
172 }
173
174 int BalloonCollection::Layout::min_balloon_width() const {
175 return ScaleSize(kBalloonMinWidth);
176 }
177
178 int BalloonCollection::Layout::max_balloon_width() const {
179 return ScaleSize(kBalloonMaxWidth);
180 }
181
182 int BalloonCollection::Layout::min_balloon_height() const {
183 return ScaleSize(kBalloonMinHeight);
184 }
185
186 int BalloonCollection::Layout::max_balloon_height() const {
187 return ScaleSize(kBalloonMaxHeight);
188 }
189
190 gfx::Point BalloonCollection::Layout::GetOrigin() const {
191 int x = 0;
192 int y = 0;
193 switch (placement_) {
194 case HORIZONTALLY_FROM_BOTTOM_LEFT:
195 x = work_area_.x();
196 y = work_area_.bottom();
197 break;
198 case HORIZONTALLY_FROM_BOTTOM_RIGHT:
199 x = work_area_.right();
200 y = work_area_.bottom();
201 break;
202 case VERTICALLY_FROM_TOP_RIGHT:
203 x = work_area_.right();
204 y = work_area_.y();
205 break;
206 case VERTICALLY_FROM_BOTTOM_RIGHT:
207 x = work_area_.right();
208 y = work_area_.bottom();
209 break;
210 default:
211 NOTREACHED();
212 break;
213 }
214 return gfx::Point(x, y);
215 }
216
217 gfx::Point BalloonCollection::Layout::NextPosition(
218 const gfx::Size& balloon_size,
219 gfx::Point* origin) const {
220 DCHECK(origin);
221
222 int x = 0;
223 int y = 0;
224 switch (placement_) {
225 case HORIZONTALLY_FROM_BOTTOM_LEFT:
226 x = origin->x();
227 y = origin->y() - balloon_size.height();
228 origin->set_x(origin->x() + balloon_size.width());
229 break;
230 case HORIZONTALLY_FROM_BOTTOM_RIGHT:
231 origin->set_x(origin->x() - balloon_size.width());
232 x = origin->x();
233 y = origin->y() - balloon_size.height();
234 break;
235 case VERTICALLY_FROM_TOP_RIGHT:
236 x = origin->x() - balloon_size.width();
237 y = origin->y();
238 origin->set_y(origin->y() + balloon_size.height());
239 break;
240 case VERTICALLY_FROM_BOTTOM_RIGHT:
241 origin->set_y(origin->y() - balloon_size.height());
242 x = origin->x() - balloon_size.width();
243 y = origin->y();
244 break;
245 default:
246 NOTREACHED();
247 break;
248 }
249 return gfx::Point(x, y);
250 }
251
252 bool BalloonCollection::Layout::RefreshSystemMetrics() {
253 bool changed = false;
254
255 gfx::Rect new_work_area(work_area_.x(), work_area_.y(),
256 work_area_.width(), work_area_.height());
257 GetMainScreenWorkArea(&new_work_area);
258 if (!work_area_.Equals(new_work_area)) {
259 work_area_.SetRect(new_work_area.x(), new_work_area.y(),
260 new_work_area.width(), new_work_area.height());
261 changed = true;
262 }
263
264 double new_font_scale_factor = font_scale_factor_;
265 new_font_scale_factor = GetSystemFontScaleFactor();
266 if (font_scale_factor_ != new_font_scale_factor) {
267 font_scale_factor_ = new_font_scale_factor;
268 changed = true;
269 }
270 return changed;
271 }
272
273 const void BalloonCollection::Layout::GetMaxLengths(
274 int* max_balloon_length,
275 int* total_length) const {
276 DCHECK(max_balloon_length && total_length);
277
278 switch (placement_) {
279 case HORIZONTALLY_FROM_BOTTOM_LEFT:
280 case HORIZONTALLY_FROM_BOTTOM_RIGHT:
281 *total_length = work_area_.width();
282 *max_balloon_length = max_balloon_width();
283 break;
284 case VERTICALLY_FROM_TOP_RIGHT:
285 case VERTICALLY_FROM_BOTTOM_RIGHT:
286 *total_length = work_area_.height();
287 *max_balloon_length = max_balloon_height();
288 break;
289 default:
290 NOTREACHED();
291 break;
292 }
293 }
294
OLDNEW
« no previous file with comments | « chrome/browser/notifications/balloon_view_win.cc ('k') | chrome/browser/notifications/balloons.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698