12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef UI_MESSAGE_CENTER_VIEWS_MESSAGE_POPUP_COLLECTION_H_ 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define UI_MESSAGE_CENTER_VIEWS_MESSAGE_POPUP_COLLECTION_H_ 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <list> 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <map> 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/compiler_specific.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/gtest_prod_util.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/weak_ptr.h" 14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/timer/timer.h" 15eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "ui/gfx/display.h" 16eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "ui/gfx/display_observer.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/native_widget_types.h" 18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/gfx/rect.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/message_center/message_center_export.h" 20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/message_center/message_center_observer.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/views/widget/widget_observer.h" 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace base { 24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class RunLoop; 25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace views { 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class Widget; 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace ash { 32a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)class WebNotificationTrayTest; 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)FORWARD_DECLARE_TEST(WebNotificationTrayTest, ManyPopupNotifications); 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace message_center { 37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace test { 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class MessagePopupCollectionTest; 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class MessageCenter; 42eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass MessageCenterTray; 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ToastContentsView; 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 45a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)enum PopupAlignment { 46a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) POPUP_ALIGNMENT_TOP = 1 << 0, 47a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) POPUP_ALIGNMENT_LEFT = 1 << 1, 48a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) POPUP_ALIGNMENT_BOTTOM = 1 << 2, 49a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) POPUP_ALIGNMENT_RIGHT = 1 << 3, 50a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}; 51a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Container for popup toasts. Because each toast is a frameless window rather 53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// than a view in a bubble, now the container just manages all of those toasts. 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This is similar to chrome/browser/notifications/balloon_collection, but the 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// contents of each toast are for the message center and layout strategy would 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// be slightly different. 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class MESSAGE_CENTER_EXPORT MessagePopupCollection 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : public MessageCenterObserver, 59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch public gfx::DisplayObserver, 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public base::SupportsWeakPtr<MessagePopupCollection> { 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // |parent| specifies the parent widget of the toast windows. The default 63bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // parent will be used for NULL. Usually each icon is spacing against its 64bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // predecessor. If |first_item_has_no_margin| is set however the first item 65bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // does not space against the tray. 66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MessagePopupCollection(gfx::NativeView parent, 67eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MessageCenter* message_center, 68bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch MessageCenterTray* tray, 69bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch bool first_item_has_no_margin); 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~MessagePopupCollection(); 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Called by ToastContentsView when its window is closed. 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void RemoveToast(ToastContentsView* toast); 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Since these events are really coming from individual toast widgets, 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // it helps to be able to keep track of the sender. 77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void OnMouseEntered(ToastContentsView* toast_entered); 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void OnMouseExited(ToastContentsView* toast_exited); 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Invoked by toasts when they start/finish their animations. 81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // While "defer counter" is greater then zero, the popup collection does 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // not perform updates. It is used to wait for various animations and user 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // actions like serial closing of the toasts, when the remaining toasts "flow 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // under the mouse". 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void IncrementDeferCounter(); 86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void DecrementDeferCounter(); 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Runs the next step in update/animate sequence, if the defer counter is not 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // zero. Otherwise, simply waits when it becomes zero. 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void DoUpdateIfPossible(); 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 92a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Updates |work_area_| and re-calculates the alignment of notification toasts 93a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // rearranging them if necessary. 94ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // This is separated from methods from OnDisplayBoundsChanged(), since 95a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // sometimes the display info has to be specified directly. One example is 96a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // shelf's auto-hide change. When the shelf in ChromeOS is temporarily shown 97a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // from auto hide status, it doesn't change the display's work area but the 98a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // actual work area for toasts should be resized. 99a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) void SetDisplayInfo(const gfx::Rect& work_area, 100a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const gfx::Rect& screen_bounds); 101ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 102eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Overridden from gfx::DislayObserver: 103eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch virtual void OnDisplayBoundsChanged(const gfx::Display& display) OVERRIDE; 104eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch virtual void OnDisplayAdded(const gfx::Display& new_display) OVERRIDE; 105eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch virtual void OnDisplayRemoved(const gfx::Display& old_display) OVERRIDE; 106eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(ash::WebNotificationTrayTest, 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ManyPopupNotifications); 110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) friend class test::MessagePopupCollectionTest; 111a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) friend class ash::WebNotificationTrayTest; 112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) typedef std::list<ToastContentsView*> Toasts; 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void CloseAllWidgets(); 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 116eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Returns the x-origin for the given toast bounds in the current work area. 117eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int GetToastOriginX(const gfx::Rect& toast_bounds); 118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Iterates toasts and starts closing the expired ones. 120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void CloseToasts(); 121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Creates new widgets for new toast notifications, and updates |toasts_| and 123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // |widgets_| correctly. 124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void UpdateWidgets(); 125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Repositions all of the widgets based on the current work area. 127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void RepositionWidgets(); 128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Repositions widgets to the top edge of the notification toast that was 130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // just removed, so that the user can click close button without mouse moves. 131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // See crbug.com/224089 132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void RepositionWidgetsWithTarget(); 133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 134a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) void ComputePopupAlignment(gfx::Rect work_area, gfx::Rect screen_bounds); 135a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 136a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // The base line is an (imaginary) line that would touch the bottom of the 137a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // next created notification if bottom-aligned or its top if top-aligned. 138a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) int GetBaseLine(ToastContentsView* last_toast); 139a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Overridden from MessageCenterObserver: 141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void OnNotificationAdded(const std::string& notification_id) OVERRIDE; 142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void OnNotificationRemoved(const std::string& notification_id, 143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool by_user) OVERRIDE; 144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void OnNotificationUpdated( 145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& notification_id) OVERRIDE; 146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ToastContentsView* FindToast(const std::string& notification_id); 148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // While the toasts are animated, avoid updating the collection, to reduce 150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // user confusion. Instead, update the collection when all animations are 151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // done. This method is run when defer counter is zero, may initiate next 152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // update/animation step. 153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void PerformDeferredTasks(); 154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void OnDeferTimerExpired(); 155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // "ForTest" methods. 157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) views::Widget* GetWidgetForTest(const std::string& id); 158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void RunLoopForTest(); 159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Rect GetToastRectAt(size_t index); 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::NativeView parent_; 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MessageCenter* message_center_; 163eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MessageCenterTray* tray_; 164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Toasts toasts_; 165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Rect work_area_; 166eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int64 display_id_; 167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 168a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Specifies which corner of the screen popups should show up. This should 169a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // ideally be the same corner the notification area (systray) is at. 170a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) PopupAlignment alignment_; 171a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int defer_counter_; 173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // This is only used to compare with incoming events, do not assume that 175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // the toast will be valid if this pointer is non-NULL. 176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ToastContentsView* latest_toast_entered_; 177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Denotes a mode when user is clicking the Close button of toasts in a 179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // sequence, w/o moving the mouse. We reposition the toasts so the next one 180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // happens to be right under the mouse, and the user can just dispose of 181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // multipel toasts by clicking. The mode ends when defer_timer_ expires. 182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool user_is_closing_toasts_by_clicking_; 183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<base::OneShotTimer<MessagePopupCollection> > defer_timer_; 184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The top edge to align the position of the next toast during 'close by 185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // clicking" mode. 186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Only to be used when user_is_closing_toasts_by_clicking_ is true. 187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int target_top_edge_; 188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Weak, only exists temporarily in tests. 190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<base::RunLoop> run_loop_for_test_; 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 192bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch // True if the first item should not have spacing against the tray. 193bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch bool first_item_has_no_margin_; 194bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(MessagePopupCollection); 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace message_center 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif // UI_MESSAGE_CENTER_VIEWS_MESSAGE_POPUP_COLLECTION_H_ 201