1 // Copyright 2014 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 COMPONENTS_INFOBARS_CORE_INFOBAR_CONTAINER_H_
6 #define COMPONENTS_INFOBARS_CORE_INFOBAR_CONTAINER_H_
10 #include "base/compiler_specific.h"
11 #include "base/time/time.h"
12 #include "components/infobars/core/infobar_manager.h"
13 #include "third_party/skia/include/core/SkColor.h"
23 // InfoBarContainer is a cross-platform base class to handle the visibility-
24 // related aspects of InfoBars. While InfoBarManager owns the InfoBars, 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.
30 class InfoBarContainer
: public InfoBarManager::Observer
{
34 // The separator color may vary depending on where the container is hosted.
35 virtual SkColor
GetInfoBarSeparatorColor() const = 0;
37 // The delegate is notified each time the infobar container changes height,
38 // as well as when it stops animating.
39 virtual void InfoBarContainerStateChanged(bool is_animating
) = 0;
41 // The delegate needs to tell us whether "unspoofable" arrows should be
42 // drawn, and if so, at what |x| coordinate. |x| may be NULL.
43 virtual bool DrawInfoBarArrows(int* x
) const = 0;
45 // Computes the target arrow height for infobar number |index|, given its
47 virtual int ArrowTargetHeightForInfoBar(
49 const gfx::SlideAnimation
& animation
) const = 0;
51 // Computes the sizes of the infobar arrow (height and half width) and bar
52 // (height) given the infobar's animation and its target element heights.
53 // |bar_target_height| may be -1, which means "use the default bar target
55 virtual void ComputeInfoBarElementSizes(
56 const gfx::SlideAnimation
& animation
,
57 int arrow_target_height
,
58 int bar_target_height
,
60 int* arrow_half_width
,
61 int* bar_height
) const = 0;
67 explicit InfoBarContainer(Delegate
* delegate
);
68 ~InfoBarContainer() override
;
70 // Changes the InfoBarManager for which this container is showing infobars.
71 // This will hide all current infobars, remove them from the container, add
72 // the infobars from |infobar_manager|, and show them all. |infobar_manager|
74 void ChangeInfoBarManager(InfoBarManager
* infobar_manager
);
76 // Returns the amount by which to overlap the toolbar above, and, when
77 // |total_height| is non-NULL, set it to the height of the InfoBarContainer
78 // (including overlap).
79 int GetVerticalOverlap(int* total_height
) const;
81 // Triggers a recalculation of all infobar arrow heights.
83 // IMPORTANT: This MUST NOT result in a call back to
84 // Delegate::InfoBarContainerStateChanged() unless it causes an actual
85 // change, lest we infinitely recurse.
86 void UpdateInfoBarArrowTargetHeights();
88 // Called when a contained infobar has animated or by some other means changed
89 // its height, or when it stops animating. The container is expected to do
90 // anything necessary to respond, e.g. re-layout.
91 void OnInfoBarStateChanged(bool is_animating
);
93 // Called by |infobar| to request that it be removed from the container. At
94 // this point, |infobar| should already be hidden.
95 void RemoveInfoBar(InfoBar
* infobar
);
97 const Delegate
* delegate() const { return delegate_
; }
100 // Subclasses must call this during destruction, so that we can remove
101 // infobars (which will call the pure virtual functions below) while the
102 // subclass portion of |this| has not yet been destroyed.
103 void RemoveAllInfoBarsForDestruction();
105 // These must be implemented on each platform to e.g. adjust the visible
106 // object hierarchy. The first two functions should each be called exactly
107 // once during an infobar's life (see comments on RemoveInfoBar() and
109 virtual void PlatformSpecificAddInfoBar(InfoBar
* infobar
,
110 size_t position
) = 0;
111 // TODO(miguelg): Remove this; it is only necessary for Android, and only
112 // until the translate infobar is implemented as three different infobars like
114 virtual void PlatformSpecificReplaceInfoBar(InfoBar
* old_infobar
,
115 InfoBar
* new_infobar
) {}
116 virtual void PlatformSpecificRemoveInfoBar(InfoBar
* infobar
) = 0;
117 virtual void PlatformSpecificInfoBarStateChanged(bool is_animating
) {}
120 typedef std::vector
<InfoBar
*> InfoBars
;
122 // InfoBarManager::Observer:
123 void OnInfoBarAdded(InfoBar
* infobar
) override
;
124 void OnInfoBarRemoved(InfoBar
* infobar
, bool animate
) override
;
125 void OnInfoBarReplaced(InfoBar
* old_infobar
, InfoBar
* new_infobar
) override
;
126 void OnManagerShuttingDown(InfoBarManager
* manager
) override
;
128 // Adds |infobar| to this container before the existing infobar at position
129 // |position| and calls Show() on it. |animate| is passed along to
131 void AddInfoBar(InfoBar
* infobar
, size_t position
, bool animate
);
134 InfoBarManager
* infobar_manager_
;
137 // Normally false. When true, OnInfoBarStateChanged() becomes a no-op. We
138 // use this to ensure that ChangeInfoBarManager() only executes the
139 // functionality in OnInfoBarStateChanged() once, to minimize unnecessary
140 // layout and painting.
141 bool ignore_infobar_state_changed_
;
143 DISALLOW_COPY_AND_ASSIGN(InfoBarContainer
);
146 } // namespace infobars
148 #endif // COMPONENTS_INFOBARS_CORE_INFOBAR_CONTAINER_H_