1 // Copyright 2015 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 "components/bubble/bubble_manager.h"
9 #include "components/bubble/bubble_controller.h"
10 #include "components/bubble/bubble_delegate.h"
12 BubbleManager::BubbleManager() : manager_state_(SHOW_BUBBLES
) {}
14 BubbleManager::~BubbleManager() {
15 FinalizePendingRequests();
18 BubbleReference
BubbleManager::ShowBubble(scoped_ptr
<BubbleDelegate
> bubble
) {
19 DCHECK(thread_checker_
.CalledOnValidThread());
22 scoped_ptr
<BubbleController
> controller(
23 new BubbleController(this, bubble
.Pass()));
25 BubbleReference bubble_ref
= controller
->AsWeakPtr();
27 switch (manager_state_
) {
30 controllers_
.push_back(controller
.Pass());
33 show_queue_
.push_back(controller
.Pass());
36 FOR_EACH_OBSERVER(BubbleManagerObserver
, observers_
,
37 OnBubbleNeverShown(controller
->AsWeakPtr()));
44 bool BubbleManager::CloseBubble(BubbleReference bubble
,
45 BubbleCloseReason reason
) {
46 DCHECK(thread_checker_
.CalledOnValidThread());
47 DCHECK_NE(manager_state_
, QUEUE_BUBBLES
);
48 if (manager_state_
== SHOW_BUBBLES
)
49 manager_state_
= QUEUE_BUBBLES
;
51 for (auto iter
= controllers_
.begin(); iter
!= controllers_
.end(); ++iter
) {
52 if (*iter
== bubble
.get()) {
53 bool closed
= (*iter
)->ShouldClose(reason
);
55 FOR_EACH_OBSERVER(BubbleManagerObserver
, observers_
,
56 OnBubbleClosed((*iter
)->AsWeakPtr(), reason
));
57 iter
= controllers_
.erase(iter
);
64 // Attempting to close a bubble that is already closed or that this manager
65 // doesn't own is a bug.
70 void BubbleManager::CloseAllBubbles(BubbleCloseReason reason
) {
71 // The following close reasons don't make sense for multiple bubbles:
72 DCHECK_NE(reason
, BUBBLE_CLOSE_ACCEPTED
);
73 DCHECK_NE(reason
, BUBBLE_CLOSE_CANCELED
);
75 DCHECK(thread_checker_
.CalledOnValidThread());
76 DCHECK_NE(manager_state_
, QUEUE_BUBBLES
);
77 if (manager_state_
== SHOW_BUBBLES
)
78 manager_state_
= QUEUE_BUBBLES
;
80 for (auto iter
= controllers_
.begin(); iter
!= controllers_
.end();) {
81 bool closed
= (*iter
)->ShouldClose(reason
);
83 FOR_EACH_OBSERVER(BubbleManagerObserver
, observers_
,
84 OnBubbleClosed((*iter
)->AsWeakPtr(), reason
));
86 iter
= closed
? controllers_
.erase(iter
) : iter
+ 1;
92 void BubbleManager::UpdateAllBubbleAnchors() {
93 DCHECK(thread_checker_
.CalledOnValidThread());
94 for (auto controller
: controllers_
)
95 controller
->UpdateAnchorPosition();
98 void BubbleManager::AddBubbleManagerObserver(BubbleManagerObserver
* observer
) {
99 observers_
.AddObserver(observer
);
102 void BubbleManager::RemoveBubbleManagerObserver(
103 BubbleManagerObserver
* observer
) {
104 observers_
.RemoveObserver(observer
);
107 void BubbleManager::FinalizePendingRequests() {
108 // Return if already "Finalized".
109 if (manager_state_
== NO_MORE_BUBBLES
)
112 manager_state_
= NO_MORE_BUBBLES
;
113 CloseAllBubbles(BUBBLE_CLOSE_FORCED
);
116 void BubbleManager::ShowPendingBubbles() {
117 if (manager_state_
== QUEUE_BUBBLES
)
118 manager_state_
= SHOW_BUBBLES
;
120 if (manager_state_
== SHOW_BUBBLES
) {
121 for (auto controller
: show_queue_
)
124 controllers_
.insert(controllers_
.end(), show_queue_
.begin(),
127 show_queue_
.weak_clear();
129 for (auto controller
: show_queue_
) {
130 FOR_EACH_OBSERVER(BubbleManagerObserver
, observers_
,
131 OnBubbleNeverShown(controller
->AsWeakPtr()));
134 // Clear the queue if bubbles can't be shown.