1 // Copyright (c) 2011 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 #ifndef CHROME_BROWSER_INFOBARS_INFOBAR_CONTAINER_H_
6 #define CHROME_BROWSER_INFOBARS_INFOBAR_CONTAINER_H_
10 #include "base/compiler_specific.h"
11 #include "base/time/time.h"
12 #include "content/public/browser/notification_observer.h"
13 #include "content/public/browser/notification_registrar.h"
14 #include "third_party/skia/include/core/SkColor.h"
17 class InfoBarDelegate;
20 // InfoBarContainer is a cross-platform base class to handle the visibility-
21 // related aspects of InfoBars. While InfoBars own themselves, the
22 // InfoBarContainer is responsible for telling particular InfoBars that they
23 // should be hidden or visible.
25 // Platforms need to subclass this to implement a few platform-specific
26 // functions, which are pure virtual here.
27 class InfoBarContainer : public content::NotificationObserver {
31 // The separator color may vary depending on where the container is hosted.
32 virtual SkColor GetInfoBarSeparatorColor() const = 0;
34 // The delegate is notified each time the infobar container changes height,
35 // as well as when it stops animating.
36 virtual void InfoBarContainerStateChanged(bool is_animating) = 0;
38 // The delegate needs to tell us whether "unspoofable" arrows should be
39 // drawn, and if so, at what |x| coordinate. |x| may be NULL.
40 virtual bool DrawInfoBarArrows(int* x) const = 0;
46 explicit InfoBarContainer(Delegate* delegate);
47 virtual ~InfoBarContainer();
49 // Changes the InfoBarService for which this container is showing infobars.
50 // This will remove all current infobars from the container, add the infobars
51 // from |infobar_service|, and show them all. |infobar_service| may be NULL.
52 void ChangeInfoBarService(InfoBarService* infobar_service);
54 // Returns the amount by which to overlap the toolbar above, and, when
55 // |total_height| is non-NULL, set it to the height of the InfoBarContainer
56 // (including overlap).
57 int GetVerticalOverlap(int* total_height);
59 // Called by the delegate when the distance between what the top infobar's
60 // "unspoofable" arrow would point to and the top infobar itself changes.
61 // This enables the top infobar to show a longer arrow (e.g. because of a
62 // visible bookmark bar) or shorter (e.g. due to being in a popup window) if
65 // IMPORTANT: This MUST NOT result in a call back to
66 // Delegate::InfoBarContainerStateChanged() unless it causes an actual
67 // change, lest we infinitely recurse.
68 void SetMaxTopArrowHeight(int height);
70 // Called when a contained infobar has animated or by some other means changed
71 // its height, or when it stops animating. The container is expected to do
72 // anything necessary to respond, e.g. re-layout.
73 void OnInfoBarStateChanged(bool is_animating);
75 // Called by |infobar| to request that it be removed from the container. At
76 // this point, |infobar| should already be hidden. Once the infobar is
77 // removed, it is guaranteed to delete itself and will not be re-added again.
78 void RemoveInfoBar(InfoBar* infobar);
80 const Delegate* delegate() const { return delegate_; }
83 // Subclasses must call this during destruction, so that we can remove
84 // infobars (which will call the pure virtual functions below) while the
85 // subclass portion of |this| has not yet been destroyed.
86 void RemoveAllInfoBarsForDestruction();
88 // These must be implemented on each platform to e.g. adjust the visible
89 // object hierarchy. The first two functions should each be called exactly
90 // once during an infobar's life (see comments on RemoveInfoBar() and
92 virtual void PlatformSpecificAddInfoBar(InfoBar* infobar,
94 virtual void PlatformSpecificRemoveInfoBar(InfoBar* infobar) = 0;
95 #if defined(OS_ANDROID)
96 // This is a temporary hook that can be removed once infobar code for
97 // Android is upstreamed and the translate infobar implemented as three
98 // different infobars like GTK does.
99 virtual void PlatformSpecificReplaceInfoBar(InfoBar* old_infobar,
100 InfoBar* new_infobar) {}
102 virtual void PlatformSpecificInfoBarStateChanged(bool is_animating) {}
105 typedef std::vector<InfoBar*> InfoBars;
107 // content::NotificationObserver:
108 virtual void Observe(int type,
109 const content::NotificationSource& source,
110 const content::NotificationDetails& details) OVERRIDE;
112 // Hides an InfoBar for the specified delegate, in response to a notification
113 // from the selected InfoBarService. The InfoBar's disappearance will be
114 // animated if |use_animation| is true. The InfoBar will call back to
115 // RemoveInfoBar() to remove itself once it's hidden (which may mean
116 // synchronously). Returns the position within |infobars_| the infobar was
118 size_t HideInfoBar(InfoBar* infobar, bool use_animation);
120 // Find an existing infobar in the container.
121 InfoBar* FindInfoBar(InfoBarDelegate* delegate);
123 // Hides all infobars in this container without animation.
124 void HideAllInfoBars();
126 void ReplaceInfoBar(InfoBarDelegate* old_delegate,
127 InfoBarDelegate* new_delegate);
129 // Adds |infobar| to this container before the existing infobar at position
130 // |position| and calls Show() on it. |animate| is passed along to
131 // infobar->Show(). Depending on the value of |callback_status|, this calls
132 // infobar->set_container(this) either before or after the call to Show() so
133 // that OnInfoBarStateChanged() either will or won't be called as a result.
135 // This should be called only once for an infobar -- once it's added, it can
136 // be repeatedly shown and hidden, but not removed and then re-added (see
137 // comments on RemoveInfoBar()).
138 enum CallbackStatus { NO_CALLBACK, WANT_CALLBACK };
139 void AddInfoBar(InfoBar* infobar,
142 CallbackStatus callback_status);
144 void UpdateInfoBarArrowTargetHeights();
145 int ArrowTargetHeightForInfoBar(size_t infobar_index) const;
147 content::NotificationRegistrar registrar_;
149 InfoBarService* infobar_service_;
152 // Calculated in SetMaxTopArrowHeight().
153 int top_arrow_target_height_;
155 DISALLOW_COPY_AND_ASSIGN(InfoBarContainer);
158 #endif // CHROME_BROWSER_INFOBARS_INFOBAR_CONTAINER_H_