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.h"
12 #include "chrome/browser/ui/search/search_model_observer.h"
13 #include "chrome/common/search_types.h"
14 #include "content/public/browser/notification_observer.h"
15 #include "content/public/browser/notification_registrar.h"
16 #include "third_party/skia/include/core/SkColor.h"
19 class InfoBarDelegate
;
23 // InfoBarContainer is a cross-platform base class to handle the visibility-
24 // related aspects of InfoBars. While InfoBars own themselves, the
25 // InfoBarContainer is responsible for telling particular InfoBars that they
26 // should be hidden or visible.
28 // Platforms need to subclass this to implement a few platform-specific
29 // functions, which are pure virtual here.
31 // This class also observes changes to the SearchModel modes. It hides infobars
32 // temporarily if the user changes into |SEARCH_SUGGESTIONS| mode (refer to
33 // SearchMode in chrome/common/search_types.h for all search modes)
35 // - |DEFAULT| page: when Instant overlay is ready;
36 // - |NTP| or |SEARCH_RESULTS| page: immediately;
37 // TODO(kuan): this scenario requires more complex synchronization with
38 // renderer SearchBoxAPI and will be implemented as the next step;
39 // for now, hiding is immediate.
40 // When the user changes back out of |SEARCH_SUGGESTIONS| mode, it reshows any
41 // infobars, and starts a 50 ms window during which any attempts to re-hide any
42 // infobars are handled without animation. This prevents glitchy-looking
43 // behavior when the user navigates following a mode change, which otherwise
44 // would re-show the infobars only to instantly animate them closed. The window
45 // to re-hide infobars without animation is canceled if a tab change occurs.
46 class InfoBarContainer
: public content::NotificationObserver
,
47 public SearchModelObserver
{
51 // The separator color may vary depending on where the container is hosted.
52 virtual SkColor
GetInfoBarSeparatorColor() const = 0;
54 // The delegate is notified each time the infobar container changes height,
55 // as well as when it stops animating.
56 virtual void InfoBarContainerStateChanged(bool is_animating
) = 0;
58 // The delegate needs to tell us whether "unspoofable" arrows should be
59 // drawn, and if so, at what |x| coordinate. |x| may be NULL.
60 virtual bool DrawInfoBarArrows(int* x
) const = 0;
66 // |search_model| may be NULL if this class is used in a window that does not
67 // support Instant Extended.
68 InfoBarContainer(Delegate
* delegate
, SearchModel
* search_model
);
69 virtual ~InfoBarContainer();
71 // Changes the InfoBarService for which this container is showing
72 // infobars. This will remove all current infobars from the container, add
73 // the infobars from |infobar_service|, and show them all. |infobar_service|
75 void ChangeInfoBarService(InfoBarService
* infobar_service
);
77 // Returns the amount by which to overlap the toolbar above, and, when
78 // |total_height| is non-NULL, set it to the height of the InfoBarContainer
79 // (including overlap).
80 int GetVerticalOverlap(int* total_height
);
82 // Called by the delegate when the distance between what the top infobar's
83 // "unspoofable" arrow would point to and the top infobar itself changes.
84 // This enables the top infobar to show a longer arrow (e.g. because of a
85 // visible bookmark bar) or shorter (e.g. due to being in a popup window) if
88 // IMPORTANT: This MUST NOT result in a call back to
89 // Delegate::InfoBarContainerStateChanged() unless it causes an actual
90 // change, lest we infinitely recurse.
91 void SetMaxTopArrowHeight(int height
);
93 // Called when a contained infobar has animated or by some other means changed
94 // its height, or when it stops animating. The container is expected to do
95 // anything necessary to respond, e.g. re-layout.
96 void OnInfoBarStateChanged(bool is_animating
);
98 // Called by |infobar| to request that it be removed from the container, as it
99 // is about to delete itself. At this point, |infobar| should already be
101 void RemoveInfoBar(InfoBar
* infobar
);
103 const Delegate
* delegate() const { return delegate_
; }
106 // Subclasses must call this during destruction, so that we can remove
107 // infobars (which will call the pure virtual functions below) while the
108 // subclass portion of |this| has not yet been destroyed.
109 void RemoveAllInfoBarsForDestruction();
111 // These must be implemented on each platform to e.g. adjust the visible
113 virtual void PlatformSpecificAddInfoBar(InfoBar
* infobar
,
114 size_t position
) = 0;
115 virtual void PlatformSpecificRemoveInfoBar(InfoBar
* infobar
) = 0;
116 virtual void PlatformSpecificInfoBarStateChanged(bool is_animating
) {}
119 typedef std::vector
<InfoBar
*> InfoBars
;
121 // content::NotificationObserver:
122 virtual void Observe(int type
,
123 const content::NotificationSource
& source
,
124 const content::NotificationDetails
& details
) OVERRIDE
;
126 // SearchModelObserver:
127 virtual void ModelChanged(const SearchModel::State
& old_state
,
128 const SearchModel::State
& new_state
) OVERRIDE
;
130 // Hides an InfoBar for the specified delegate, in response to a notification
131 // from the selected InfoBarService. The InfoBar's disappearance will be
132 // animated if |use_animation| is true and it has been more than 50ms since
133 // infobars were reshown due to an Instant Extended mode change. The InfoBar
134 // will call back to RemoveInfoBar() to remove itself once it's hidden (which
135 // may mean synchronously). Returns the position within |infobars_| the
136 // infobar was previously at.
137 size_t HideInfoBar(InfoBarDelegate
* delegate
, bool use_animation
);
139 // Hides all infobars in this container without animation.
140 void HideAllInfoBars();
142 // Adds |infobar| to this container before the existing infobar at position
143 // |position| and calls Show() on it. |animate| is passed along to
144 // infobar->Show(). Depending on the value of |callback_status|, this calls
145 // infobar->set_container(this) either before or after the call to Show() so
146 // that OnInfoBarStateChanged() either will or won't be called as a result.
147 enum CallbackStatus
{ NO_CALLBACK
, WANT_CALLBACK
};
148 void AddInfoBar(InfoBar
* infobar
,
151 CallbackStatus callback_status
);
153 void UpdateInfoBarArrowTargetHeights();
154 int ArrowTargetHeightForInfoBar(size_t infobar_index
) const;
156 content::NotificationRegistrar registrar_
;
158 InfoBarService
* infobar_service_
;
161 // Tracks whether infobars in the container are shown or hidden.
162 bool infobars_shown_
;
164 // Tracks the most recent time infobars were re-shown after being hidden due
165 // to Instant Extended's ModeChanged.
166 base::TimeTicks infobars_shown_time_
;
168 // Tracks which search mode is active, as well as mode changes, for Instant
170 SearchModel
* search_model_
;
172 // Calculated in SetMaxTopArrowHeight().
173 int top_arrow_target_height_
;
175 DISALLOW_COPY_AND_ASSIGN(InfoBarContainer
);
178 #endif // CHROME_BROWSER_INFOBARS_INFOBAR_CONTAINER_H_