OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Draws the view for the balloons. | 5 // Draws the view for the balloons. |
6 | 6 |
7 #include "chrome/browser/chromeos/notifications/notification_panel.h" | 7 #include "chrome/browser/chromeos/notifications/notification_panel.h" |
8 | 8 |
9 #include "app/gfx/canvas.h" | 9 #include "app/gfx/canvas.h" |
10 #include "app/l10n_util.h" | 10 #include "app/l10n_util.h" |
(...skipping 24 matching lines...) Expand all Loading... |
35 class PanelWidget : public views::WidgetGtk { | 35 class PanelWidget : public views::WidgetGtk { |
36 public: | 36 public: |
37 explicit PanelWidget(chromeos::NotificationPanel* panel) | 37 explicit PanelWidget(chromeos::NotificationPanel* panel) |
38 : WidgetGtk(views::WidgetGtk::TYPE_WINDOW), | 38 : WidgetGtk(views::WidgetGtk::TYPE_WINDOW), |
39 panel_(panel) { | 39 panel_(panel) { |
40 } | 40 } |
41 | 41 |
42 // views::WidgetGtk overrides. | 42 // views::WidgetGtk overrides. |
43 virtual gboolean OnMotionNotify(GtkWidget* widget, GdkEventMotion* event) { | 43 virtual gboolean OnMotionNotify(GtkWidget* widget, GdkEventMotion* event) { |
44 gboolean result = WidgetGtk::OnMotionNotify(widget, event); | 44 gboolean result = WidgetGtk::OnMotionNotify(widget, event); |
45 panel_->DontUpdatePanelOnStale(); | 45 panel_->OnMouseMotion(); |
46 return result; | 46 return result; |
47 } | 47 } |
48 | 48 |
49 virtual gboolean OnLeaveNotify(GtkWidget* widget, GdkEventCrossing* event) { | 49 virtual gboolean OnLeaveNotify(GtkWidget* widget, GdkEventCrossing* event) { |
50 gboolean result = views::WidgetGtk::OnLeaveNotify(widget, event); | 50 gboolean result = views::WidgetGtk::OnLeaveNotify(widget, event); |
51 // Leave notify can happen if the mouse moves into the child gdk window. | 51 // Leave notify can happen if the mouse moves into the child gdk window. |
52 // Make sure the mouse is outside of the panel. | 52 // Make sure the mouse is outside of the panel. |
53 gfx::Point p(event->x_root, event->y_root); | 53 gfx::Point p(event->x_root, event->y_root); |
54 gfx::Rect bounds; | 54 gfx::Rect bounds; |
55 GetBounds(&bounds, true); | 55 GetBounds(&bounds, true); |
(...skipping 16 matching lines...) Expand all Loading... |
72 | 72 |
73 virtual ~BalloonSubContainer() {} | 73 virtual ~BalloonSubContainer() {} |
74 | 74 |
75 // views::View overrides. | 75 // views::View overrides. |
76 virtual gfx::Size GetPreferredSize() { | 76 virtual gfx::Size GetPreferredSize() { |
77 return preferred_size_; | 77 return preferred_size_; |
78 } | 78 } |
79 | 79 |
80 virtual void Layout() { | 80 virtual void Layout() { |
81 // Layout bottom up | 81 // Layout bottom up |
82 int count = GetChildViewCount(); | |
83 int height = 0; | 82 int height = 0; |
84 for (int i = count - 1; i >= 0; --i) { | 83 for (int i = GetChildViewCount() - 1; i >= 0; --i) { |
85 views::View* child = GetChildViewAt(i); | 84 views::View* child = GetChildViewAt(i); |
86 child->SetBounds(0, height, child->width(), child->height()); | 85 child->SetBounds(0, height, child->width(), child->height()); |
87 height += child->height() + margin_; | 86 height += child->height() + margin_; |
88 } | 87 } |
89 SchedulePaint(); | 88 SchedulePaint(); |
90 } | 89 } |
91 | 90 |
92 // Updates the bound so that it can show all balloons. | 91 // Updates the bound so that it can show all balloons. |
93 void UpdateBounds() { | 92 void UpdateBounds() { |
94 int height = 0; | 93 int height = 0; |
95 int max_width = 0; | 94 int max_width = 0; |
96 for (int i = GetChildViewCount() - 1; i >= 0; --i) { | 95 for (int i = GetChildViewCount() - 1; i >= 0; --i) { |
97 views::View* c = GetChildViewAt(i); | 96 views::View* child = GetChildViewAt(i); |
98 height += c->height() + margin_; | 97 height += child->height() + margin_; |
99 max_width = std::max(max_width, c->width()); | 98 max_width = std::max(max_width, child->width()); |
100 } | 99 } |
101 if (height > 0) | 100 if (height > 0) |
102 height -= margin_; | 101 height -= margin_; |
103 preferred_size_.set_width(max_width); | 102 preferred_size_.set_width(max_width); |
104 preferred_size_.set_height(height); | 103 preferred_size_.set_height(height); |
105 SizeToPreferredSize(); | 104 SizeToPreferredSize(); |
106 } | 105 } |
107 | 106 |
108 // Returns the bounds that covers new notifications. | 107 // Returns the bounds that covers new notifications. |
109 gfx::Rect GetNewBounds() { | 108 gfx::Rect GetNewBounds() { |
110 gfx::Rect rect; | 109 gfx::Rect rect; |
111 for (int i = GetChildViewCount() - 1; i >= 0; --i) { | 110 for (int i = GetChildViewCount() - 1; i >= 0; --i) { |
112 BalloonViewImpl* view = | 111 BalloonViewImpl* view = |
113 static_cast<BalloonViewImpl*>(GetChildViewAt(i)); | 112 static_cast<BalloonViewImpl*>(GetChildViewAt(i)); |
114 if (!view->stale()) { | 113 if (!view->stale()) { |
115 if (rect.IsEmpty()) { | 114 if (rect.IsEmpty()) { |
116 rect = view->bounds(); | 115 rect = view->bounds(); |
117 } else { | 116 } else { |
118 rect = rect.Union(bounds()); | 117 rect = rect.Union(view->bounds()); |
119 } | 118 } |
120 } | 119 } |
121 } | 120 } |
122 return gfx::Rect(x(), y(), rect.width(), rect.height()); | 121 return gfx::Rect(x(), y(), rect.width(), rect.height()); |
123 } | 122 } |
124 | 123 |
125 // Returns # of new notifications. | 124 // Returns # of new notifications. |
126 int GetNewCount() { | 125 int GetNewCount() { |
127 int count = 0; | 126 int count = 0; |
128 for (int i = GetChildViewCount() - 1; i >= 0; --i) { | 127 for (int i = GetChildViewCount() - 1; i >= 0; --i) { |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
176 0, sticky_container_->bounds().bottom() + margin, | 175 0, sticky_container_->bounds().bottom() + margin, |
177 width(), non_sticky_container_->height()); | 176 width(), non_sticky_container_->height()); |
178 } | 177 } |
179 | 178 |
180 virtual gfx::Size GetPreferredSize() { | 179 virtual gfx::Size GetPreferredSize() { |
181 return preferred_size_; | 180 return preferred_size_; |
182 } | 181 } |
183 | 182 |
184 // Returns the size that covers sticky and new notifications. | 183 // Returns the size that covers sticky and new notifications. |
185 gfx::Size GetStickyNewSize() { | 184 gfx::Size GetStickyNewSize() { |
186 gfx::Rect new_sticky = sticky_container_->bounds(); | 185 gfx::Rect sticky = sticky_container_->bounds(); |
187 gfx::Rect new_non_sticky = non_sticky_container_->GetNewBounds(); | 186 gfx::Rect new_non_sticky = non_sticky_container_->GetNewBounds(); |
188 if (new_sticky.IsEmpty()) | 187 if (sticky.IsEmpty()) |
189 return new_non_sticky.size(); | 188 return new_non_sticky.size(); |
190 if (new_non_sticky.IsEmpty()) | 189 if (new_non_sticky.IsEmpty()) |
191 return new_sticky.size(); | 190 return sticky.size(); |
192 return new_sticky.Union(new_non_sticky).size(); | 191 return sticky.Union(new_non_sticky).size(); |
193 } | 192 } |
194 | 193 |
195 // Adds a ballon to the panel. | 194 // Adds a ballon to the panel. |
196 void Add(Balloon* balloon) { | 195 void Add(Balloon* balloon) { |
197 BalloonViewImpl* view = | 196 BalloonViewImpl* view = |
198 static_cast<BalloonViewImpl*>(balloon->view()); | 197 static_cast<BalloonViewImpl*>(balloon->view()); |
199 GetContainerFor(balloon)->AddChildView(view); | 198 GetContainerFor(balloon)->AddChildView(view); |
200 } | 199 } |
201 | 200 |
202 // Updates the position of the |balloon|. | 201 // Updates the position of the |balloon|. |
(...skipping 22 matching lines...) Expand all Loading... |
225 GetContainerFor(balloon)->RemoveChildView(view); | 224 GetContainerFor(balloon)->RemoveChildView(view); |
226 } | 225 } |
227 | 226 |
228 // Returns the number of notifications added to the panel. | 227 // Returns the number of notifications added to the panel. |
229 int GetNotificationCount() { | 228 int GetNotificationCount() { |
230 return sticky_container_->GetChildViewCount() + | 229 return sticky_container_->GetChildViewCount() + |
231 non_sticky_container_->GetChildViewCount(); | 230 non_sticky_container_->GetChildViewCount(); |
232 } | 231 } |
233 | 232 |
234 // Returns the # of new notifications. | 233 // Returns the # of new notifications. |
235 bool GetNewNotificationCount() { | 234 int GetNewNotificationCount() { |
236 return sticky_container_->GetNewCount() + | 235 return sticky_container_->GetNewCount() + |
237 non_sticky_container_->GetNewCount(); | 236 non_sticky_container_->GetNewCount(); |
238 } | 237 } |
239 | 238 |
| 239 // Returns the # of sticky and new notifications. |
| 240 int GetStickyNewNotificationCount() { |
| 241 return sticky_container_->GetChildViewCount() + |
| 242 non_sticky_container_->GetNewCount(); |
| 243 } |
| 244 |
240 // Returns the # of sticky notifications. | 245 // Returns the # of sticky notifications. |
241 bool GetStickyNotificationCount() { | 246 int GetStickyNotificationCount() { |
242 return sticky_container_->GetChildViewCount(); | 247 return sticky_container_->GetChildViewCount(); |
243 } | 248 } |
244 | 249 |
245 // Returns true if the |view| is contained in the panel. | 250 // Returns true if the |view| is contained in the panel. |
246 bool HasBalloonView(View* view) { | 251 bool HasBalloonView(View* view) { |
247 return sticky_container_->HasChildView(view) || | 252 return sticky_container_->HasChildView(view) || |
248 non_sticky_container_->HasChildView(view); | 253 non_sticky_container_->HasChildView(view); |
249 } | 254 } |
250 | 255 |
251 // Updates the bounds so that all notifications are visible. | 256 // Updates the bounds so that all notifications are visible. |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
284 BalloonSubContainer* non_sticky_container_; | 289 BalloonSubContainer* non_sticky_container_; |
285 gfx::Size preferred_size_; | 290 gfx::Size preferred_size_; |
286 | 291 |
287 DISALLOW_COPY_AND_ASSIGN(BalloonContainer); | 292 DISALLOW_COPY_AND_ASSIGN(BalloonContainer); |
288 }; | 293 }; |
289 | 294 |
290 NotificationPanel::NotificationPanel() | 295 NotificationPanel::NotificationPanel() |
291 : balloon_container_(NULL), | 296 : balloon_container_(NULL), |
292 state_(CLOSED), | 297 state_(CLOSED), |
293 task_factory_(this), | 298 task_factory_(this), |
294 update_panel_on_mouse_leave_(false), | 299 min_bounds_(0, 0, kBalloonMinWidth, kBalloonMinHeight) { |
295 latest_token_(0), | |
296 stale_token_(0) { | |
297 Init(); | 300 Init(); |
298 } | 301 } |
299 | 302 |
300 NotificationPanel::~NotificationPanel() { | 303 NotificationPanel::~NotificationPanel() { |
301 Hide(); | 304 Hide(); |
302 } | 305 } |
303 | 306 |
304 //////////////////////////////////////////////////////////////////////////////// | 307 //////////////////////////////////////////////////////////////////////////////// |
305 // NottificationPanel public. | 308 // NottificationPanel public. |
306 | 309 |
307 void NotificationPanel::Show() { | 310 void NotificationPanel::Show() { |
308 if (!panel_widget_.get()) { | 311 if (!panel_widget_.get()) { |
309 // TODO(oshima): Using window because Popup widget behaves weird | 312 // TODO(oshima): Using window because Popup widget behaves weird |
310 // when resizing. This needs to be investigated. | 313 // when resizing. This needs to be investigated. |
311 panel_widget_.reset(new PanelWidget(this)); | 314 panel_widget_.reset(new PanelWidget(this)); |
312 gfx::Rect bounds = GetPreferredBounds(); | 315 gfx::Rect bounds = GetPreferredBounds(); |
313 if (bounds.width() < kBalloonMinWidth || | 316 bounds = bounds.Union(min_bounds_); |
314 bounds.height() < kBalloonMinHeight) { | |
315 // Gtk uses its own default size when the size is empty. | |
316 // Use the minimum size as a default. | |
317 bounds.SetRect(0, 0, kBalloonMinWidth, kBalloonMinHeight); | |
318 } | |
319 panel_widget_->Init(NULL, bounds); | 317 panel_widget_->Init(NULL, bounds); |
320 // TODO(oshima): I needed the following code in order to get sizing | 318 // TODO(oshima): I needed the following code in order to get sizing |
321 // reliably. Investigate and fix it in WidgetGtk. | 319 // reliably. Investigate and fix it in WidgetGtk. |
322 gtk_widget_set_size_request(GTK_WIDGET(panel_widget_->GetNativeView()), | 320 gtk_widget_set_size_request(GTK_WIDGET(panel_widget_->GetNativeView()), |
323 bounds.width(), bounds.height()); | 321 bounds.width(), bounds.height()); |
324 panel_widget_->SetContentsView(scroll_view_.get()); | 322 panel_widget_->SetContentsView(scroll_view_.get()); |
325 panel_controller_.reset( | 323 panel_controller_.reset( |
326 new PanelController(this, | 324 new PanelController(this, |
327 GTK_WINDOW(panel_widget_->GetNativeView()), | 325 GTK_WINDOW(panel_widget_->GetNativeView()), |
328 gfx::Rect(0, 0, kBalloonMinWidth, 1))); | 326 gfx::Rect(0, 0, kBalloonMinWidth, 1))); |
329 } | 327 } |
330 panel_widget_->Show(); | 328 panel_widget_->Show(); |
331 } | 329 } |
332 | 330 |
333 void NotificationPanel::Hide() { | 331 void NotificationPanel::Hide() { |
334 if (panel_widget_.get()) { | 332 if (panel_widget_.get()) { |
335 // We need to remove & detach the scroll view from hierarchy to | 333 // We need to remove & detach the scroll view from hierarchy to |
336 // avoid GTK deleting child. | 334 // avoid GTK deleting child. |
337 // TODO(oshima): handle this details in WidgetGtk. | 335 // TODO(oshima): handle this details in WidgetGtk. |
338 panel_widget_->GetRootView()->RemoveChildView(scroll_view_.get()); | 336 panel_widget_->GetRootView()->RemoveChildView(scroll_view_.get()); |
339 panel_widget_.release()->Close(); | 337 panel_widget_.release()->Close(); |
340 panel_controller_.release()->Close(); | 338 panel_controller_.release()->Close(); |
341 } | 339 } |
342 } | 340 } |
343 | 341 |
344 int NotificationPanel::GetStickyNotificationCount() const { | |
345 return balloon_container_->GetStickyNotificationCount(); | |
346 } | |
347 | |
348 int NotificationPanel::GetNewNotificationCount() const { | |
349 return balloon_container_->GetNewNotificationCount(); | |
350 } | |
351 | |
352 //////////////////////////////////////////////////////////////////////////////// | 342 //////////////////////////////////////////////////////////////////////////////// |
353 // BalloonCollectionImpl::NotificationUI overrides. | 343 // BalloonCollectionImpl::NotificationUI overrides. |
354 | 344 |
355 void NotificationPanel::Add(Balloon* balloon) { | 345 void NotificationPanel::Add(Balloon* balloon) { |
356 balloon_container_->Add(balloon); | 346 balloon_container_->Add(balloon); |
357 if (state_ == CLOSED || state_ == MINIMIZED) | 347 if (state_ == CLOSED || state_ == MINIMIZED || state_ == KEEP_SIZE) |
358 state_ = STICKY_AND_NEW; | 348 state_ = STICKY_AND_NEW; |
359 Show(); | 349 Show(); |
360 UpdatePanel(true); | 350 UpdatePanel(true); |
361 StartStaleTimer(balloon); | 351 StartStaleTimer(balloon); |
362 } | 352 } |
363 | 353 |
364 bool NotificationPanel::Update(Balloon* balloon) { | 354 bool NotificationPanel::Update(Balloon* balloon) { |
365 if (balloon_container_->Update(balloon)) { | 355 if (balloon_container_->Update(balloon)) { |
366 if (state_ == CLOSED || state_ == MINIMIZED) | 356 if (state_ == CLOSED || state_ == MINIMIZED) |
367 state_ = STICKY_AND_NEW; | 357 state_ = STICKY_AND_NEW; |
368 Show(); | 358 Show(); |
369 UpdatePanel(true); | 359 UpdatePanel(true); |
370 StartStaleTimer(balloon); | 360 StartStaleTimer(balloon); |
371 return true; | 361 return true; |
372 } else { | 362 } else { |
373 return false; | 363 return false; |
374 } | 364 } |
375 } | 365 } |
376 | 366 |
377 void NotificationPanel::Remove(Balloon* balloon) { | 367 void NotificationPanel::Remove(Balloon* balloon) { |
378 balloon_container_->Remove(balloon); | 368 balloon_container_->Remove(balloon); |
379 // no change to the state | 369 // no change to the state |
380 if (balloon_container_->GetNotificationCount() == 0) | 370 if (balloon_container_->GetNotificationCount() == 0) |
381 state_ = CLOSED; | 371 state_ = CLOSED; |
382 if (static_cast<BalloonViewImpl*>(balloon->view())->closed_by_user()) { | 372 if (state_ == KEEP_SIZE) { |
383 DontUpdatePanelOnStale(); | 373 // Just update the content. |
384 balloon_container_->UpdateBounds(); | 374 balloon_container_->UpdateBounds(); |
385 scroll_view_->Layout(); | 375 scroll_view_->Layout(); |
386 } else { | 376 } else { |
387 UpdatePanel(true); | 377 UpdatePanel(true); |
388 } | 378 } |
389 } | 379 } |
390 | 380 |
391 void NotificationPanel::ResizeNotification( | 381 void NotificationPanel::ResizeNotification( |
392 Balloon* balloon, const gfx::Size& size) { | 382 Balloon* balloon, const gfx::Size& size) { |
393 // restrict to the min & max sizes | 383 // restrict to the min & max sizes |
(...skipping 19 matching lines...) Expand all Loading... |
413 } | 403 } |
414 | 404 |
415 void NotificationPanel::ClosePanel() { | 405 void NotificationPanel::ClosePanel() { |
416 state_ = CLOSED; | 406 state_ = CLOSED; |
417 UpdatePanel(false); | 407 UpdatePanel(false); |
418 } | 408 } |
419 | 409 |
420 void NotificationPanel::OnPanelStateChanged(PanelController::State state) { | 410 void NotificationPanel::OnPanelStateChanged(PanelController::State state) { |
421 switch (state) { | 411 switch (state) { |
422 case PanelController::EXPANDED: | 412 case PanelController::EXPANDED: |
423 // Geting expanded in STICKY_AND_NEW state means that a new | 413 // Geting expanded in STICKY_AND_NEW or in KEEP_SIZE state means |
424 // notification is added, so just leave the state. Otherwise, | 414 // that a new notification is added, so just leave the |
425 // expand to full. | 415 // state. Otherwise, expand to full. |
426 if (state_ != STICKY_AND_NEW) | 416 if (state_ != STICKY_AND_NEW && state_ != KEEP_SIZE) |
427 state_ = FULL; | 417 state_ = FULL; |
428 // When the panel is to be expanded, we either show all, or | 418 // When the panel is to be expanded, we either show all, or |
429 // show only sticky/new, depending on the state. | 419 // show only sticky/new, depending on the state. |
430 UpdatePanel(false); | 420 UpdatePanel(false); |
431 break; | 421 break; |
432 case PanelController::MINIMIZED: | 422 case PanelController::MINIMIZED: |
433 state_ = MINIMIZED; | 423 state_ = MINIMIZED; |
434 // Make all notifications stale when a user minimize the panel. | 424 // Make all notifications stale when a user minimize the panel. |
435 balloon_container_->MakeAllStale(); | 425 balloon_container_->MakeAllStale(); |
436 break; | 426 break; |
437 } | 427 } |
438 } | 428 } |
439 | 429 |
440 void NotificationPanel::OnMouseLeave() { | 430 void NotificationPanel::OnMouseLeave() { |
441 if (update_panel_on_mouse_leave_) { | 431 if (balloon_container_->GetNotificationCount() == 0) { |
442 // TODO(oshima): We need "AS_IS" state, which simply | 432 state_ = CLOSED; |
443 // keeps the current panel size unless it has less notifications | |
444 // than it can show. | |
445 if (balloon_container_->GetStickyNotificationCount() > 0 || | |
446 balloon_container_->GetNewNotificationCount() > 0) { | |
447 state_ = STICKY_AND_NEW; | |
448 } else { | |
449 state_ = MINIMIZED; | |
450 } | |
451 UpdatePanel(true); | |
452 } | 433 } |
| 434 UpdatePanel(true); |
| 435 } |
| 436 |
| 437 void NotificationPanel::OnMouseMotion() { |
| 438 state_ = KEEP_SIZE; |
| 439 } |
| 440 |
| 441 NotificationPanelTester* NotificationPanel::GetTester() { |
| 442 if (!tester_.get()) { |
| 443 tester_.reset(new NotificationPanelTester(this)); |
| 444 } |
| 445 return tester_.get(); |
453 } | 446 } |
454 | 447 |
455 //////////////////////////////////////////////////////////////////////////////// | 448 //////////////////////////////////////////////////////////////////////////////// |
456 // NotificationPanel private. | 449 // NotificationPanel private. |
457 | 450 |
458 void NotificationPanel::Init() { | 451 void NotificationPanel::Init() { |
459 DCHECK(!panel_widget_.get()); | 452 DCHECK(!panel_widget_.get()); |
460 balloon_container_ = new BalloonContainer(1); | 453 balloon_container_ = new BalloonContainer(1); |
461 balloon_container_->set_background( | 454 balloon_container_->set_background( |
462 views::Background::CreateSolidBackground(ResourceBundle::frame_color)); | 455 views::Background::CreateSolidBackground(ResourceBundle::frame_color)); |
463 | 456 |
464 scroll_view_.reset(new views::ScrollView()); | 457 scroll_view_.reset(new views::ScrollView()); |
465 scroll_view_->set_parent_owned(false); | 458 scroll_view_->set_parent_owned(false); |
466 scroll_view_->SetContents(balloon_container_); | 459 scroll_view_->SetContents(balloon_container_); |
467 scroll_view_->set_background( | 460 scroll_view_->set_background( |
468 views::Background::CreateSolidBackground(SK_ColorWHITE)); | 461 views::Background::CreateSolidBackground(SK_ColorWHITE)); |
469 } | 462 } |
470 | 463 |
471 void NotificationPanel::UpdatePanel(bool contents_changed) { | 464 void NotificationPanel::UpdatePanel(bool contents_changed) { |
472 update_panel_on_mouse_leave_ = false; | |
473 if (contents_changed) { | 465 if (contents_changed) { |
474 balloon_container_->UpdateBounds(); | 466 balloon_container_->UpdateBounds(); |
475 scroll_view_->Layout(); | 467 scroll_view_->Layout(); |
476 } | 468 } |
477 switch(state_) { | 469 switch(state_) { |
| 470 case KEEP_SIZE: { |
| 471 gfx::Rect min_bounds = GetPreferredBounds(); |
| 472 gfx::Rect panel_bounds; |
| 473 panel_widget_->GetBounds(&panel_bounds, true); |
| 474 if (min_bounds.height() < panel_bounds.height()) |
| 475 panel_widget_->SetBounds(min_bounds); |
| 476 // no change. |
| 477 break; |
| 478 } |
478 case CLOSED: | 479 case CLOSED: |
479 balloon_container_->MakeAllStale(); | 480 balloon_container_->MakeAllStale(); |
480 Hide(); | 481 Hide(); |
481 break; | 482 break; |
482 case MINIMIZED: | 483 case MINIMIZED: |
483 balloon_container_->MakeAllStale(); | 484 balloon_container_->MakeAllStale(); |
484 if (panel_controller_.get()) | 485 if (panel_controller_.get()) |
485 panel_controller_->SetState(PanelController::MINIMIZED); | 486 panel_controller_->SetState(PanelController::MINIMIZED); |
486 break; | 487 break; |
487 case FULL: | 488 case FULL: |
(...skipping 11 matching lines...) Expand all Loading... |
499 } | 500 } |
500 } | 501 } |
501 | 502 |
502 gfx::Rect NotificationPanel::GetPreferredBounds() { | 503 gfx::Rect NotificationPanel::GetPreferredBounds() { |
503 gfx::Size pref_size = balloon_container_->GetPreferredSize(); | 504 gfx::Size pref_size = balloon_container_->GetPreferredSize(); |
504 int new_height = std::min(pref_size.height(), kMaxPanelHeight); | 505 int new_height = std::min(pref_size.height(), kMaxPanelHeight); |
505 int new_width = pref_size.width(); | 506 int new_width = pref_size.width(); |
506 // Adjust the width to avoid showing a horizontal scroll bar. | 507 // Adjust the width to avoid showing a horizontal scroll bar. |
507 if (new_height != pref_size.height()) | 508 if (new_height != pref_size.height()) |
508 new_width += scroll_view_->GetScrollBarWidth(); | 509 new_width += scroll_view_->GetScrollBarWidth(); |
509 return gfx::Rect(0, 0, new_width, new_height); | 510 return gfx::Rect(0, 0, new_width, new_height).Union(min_bounds_); |
510 } | 511 } |
511 | 512 |
512 gfx::Rect NotificationPanel::GetStickyNewBounds() { | 513 gfx::Rect NotificationPanel::GetStickyNewBounds() { |
513 gfx::Size pref_size = balloon_container_->GetPreferredSize(); | 514 gfx::Size pref_size = balloon_container_->GetPreferredSize(); |
514 gfx::Size sticky_size = balloon_container_->GetStickyNewSize(); | 515 gfx::Size sticky_size = balloon_container_->GetStickyNewSize(); |
515 int new_height = std::min(sticky_size.height(), kMaxPanelHeight); | 516 int new_height = std::min(sticky_size.height(), kMaxPanelHeight); |
516 int new_width = pref_size.width(); | 517 int new_width = pref_size.width(); |
517 // Adjust the width to avoid showing a horizontal scroll bar. | 518 // Adjust the width to avoid showing a horizontal scroll bar. |
518 if (new_height != pref_size.height()) | 519 if (new_height != pref_size.height()) |
519 new_width += scroll_view_->GetScrollBarWidth(); | 520 new_width += scroll_view_->GetScrollBarWidth(); |
520 return gfx::Rect(0, 0, new_width, new_height); | 521 return gfx::Rect(0, 0, new_width, new_height).Union(min_bounds_); |
521 } | |
522 | |
523 void NotificationPanel::DontUpdatePanelOnStale() { | |
524 if (stale_token_ != latest_token_) { | |
525 stale_token_ = latest_token_; | |
526 } | |
527 update_panel_on_mouse_leave_ = true; | |
528 } | 522 } |
529 | 523 |
530 void NotificationPanel::StartStaleTimer(Balloon* balloon) { | 524 void NotificationPanel::StartStaleTimer(Balloon* balloon) { |
531 BalloonViewImpl* view = static_cast<BalloonViewImpl*>(balloon->view()); | 525 BalloonViewImpl* view = static_cast<BalloonViewImpl*>(balloon->view()); |
532 MessageLoop::current()->PostDelayedTask( | 526 MessageLoop::current()->PostDelayedTask( |
533 FROM_HERE, | 527 FROM_HERE, |
534 task_factory_.NewRunnableMethod( | 528 task_factory_.NewRunnableMethod( |
535 &NotificationPanel::OnStale, view, latest_token_++), | 529 &NotificationPanel::OnStale, view), |
536 1000 * kStaleTimeoutInSeconds); | 530 1000 * kStaleTimeoutInSeconds); |
537 } | 531 } |
538 | 532 |
539 void NotificationPanel::OnStale(BalloonViewImpl* view, int token) { | 533 void NotificationPanel::OnStale(BalloonViewImpl* view) { |
540 if (balloon_container_->HasBalloonView(view) && !view->stale()) { | 534 if (balloon_container_->HasBalloonView(view) && !view->stale()) { |
541 view->set_stale(); | 535 view->set_stale(); |
542 // don't update panel on stale | 536 // don't update panel on stale |
543 if (token < stale_token_) { | 537 if (state_ == KEEP_SIZE) |
544 return; | 538 return; |
545 } | 539 if (balloon_container_->GetStickyNewNotificationCount() > 0) { |
546 if (balloon_container_->GetStickyNotificationCount() > 0) { | |
547 state_ = STICKY_AND_NEW; | 540 state_ = STICKY_AND_NEW; |
548 } else { | 541 } else { |
549 state_ = MINIMIZED; | 542 state_ = MINIMIZED; |
550 } | 543 } |
551 UpdatePanel(false); | 544 UpdatePanel(false); |
552 } | 545 } |
553 } | 546 } |
554 | 547 |
| 548 //////////////////////////////////////////////////////////////////////////////// |
| 549 // NotificationPanelTester public. |
| 550 |
| 551 int NotificationPanelTester::GetNotificationCount() const { |
| 552 return panel_->balloon_container_->GetNotificationCount(); |
| 553 } |
| 554 |
| 555 int NotificationPanelTester::GetStickyNotificationCount() const { |
| 556 return panel_->balloon_container_->GetStickyNotificationCount(); |
| 557 } |
| 558 |
| 559 int NotificationPanelTester::GetNewNotificationCount() const { |
| 560 return panel_->balloon_container_->GetNewNotificationCount(); |
| 561 } |
| 562 |
| 563 |
555 } // namespace chromeos | 564 } // namespace chromeos |
OLD | NEW |