1 // Copyright (c) 2012 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. 4 5 #ifndef CHROME_BROWSER_INFOBARS_INFOBAR_H_ 6 #define CHROME_BROWSER_INFOBARS_INFOBAR_H_ 7 8 #include <utility> 9 10 #include "base/memory/scoped_ptr.h" 11 #include "chrome/browser/infobars/infobar_delegate.h" 12 #include "third_party/skia/include/core/SkColor.h" 13 #include "ui/gfx/animation/animation_delegate.h" 14 #include "ui/gfx/animation/slide_animation.h" 15 #include "ui/gfx/size.h" 16 17 class InfoBarContainer; 18 class InfoBarService; 19 20 // InfoBar is a cross-platform base class for an infobar "view" (in the MVC 21 // sense), which owns a corresponding InfoBarDelegate "model". Typically, 22 // a caller will call XYZInfoBarDelegate::Create() and pass in the 23 // InfoBarService for the relevant tab. This will create an XYZInfoBarDelegate, 24 // create a platform-specific subclass of InfoBar to own it, and then call 25 // InfoBarService::AddInfoBar() to give it ownership of the infobar. 26 // During its life, the InfoBar may be shown and hidden as the owning tab is 27 // switched between the foreground and background. Eventually, InfoBarService 28 // will instruct the InfoBar to close itself. At this point, the InfoBar will 29 // optionally animate closed; once it's no longer visible, it deletes itself, 30 // destroying the InfoBarDelegate in the process. 31 // 32 // Thus, InfoBarDelegate and InfoBar implementations can assume they share 33 // lifetimes, and not NULL-check each other; but if one needs to reach back into 34 // the owning InfoBarService, it must check whether that's still possible. 35 class InfoBar : public gfx::AnimationDelegate { 36 public: 37 // These are the types passed as Details for infobar-related notifications. 38 typedef InfoBar AddedDetails; 39 typedef std::pair<InfoBar*, bool> RemovedDetails; 40 typedef std::pair<InfoBar*, InfoBar*> ReplacedDetails; 41 42 // Platforms must define these. 43 static const int kDefaultBarTargetHeight; 44 static const int kSeparatorLineHeight; 45 static const int kDefaultArrowTargetHeight; 46 static const int kMaximumArrowTargetHeight; 47 // The half-width (see comments on |arrow_half_width_| below) scales to its 48 // default and maximum values proportionally to how the height scales to its. 49 static const int kDefaultArrowTargetHalfWidth; 50 static const int kMaximumArrowTargetHalfWidth; 51 52 explicit InfoBar(scoped_ptr<InfoBarDelegate> delegate); 53 virtual ~InfoBar(); 54 55 static SkColor GetTopColor(InfoBarDelegate::Type infobar_type); 56 static SkColor GetBottomColor(InfoBarDelegate::Type infobar_type); 57 58 InfoBarService* owner() { return owner_; } 59 InfoBarDelegate* delegate() { return delegate_.get(); } 60 const InfoBarDelegate* delegate() const { return delegate_.get(); } 61 void set_container(InfoBarContainer* container) { container_ = container; } 62 63 // Sets |owner_|. This also calls StoreActiveEntryUniqueID() on |delegate_|. 64 // This must only be called once as there's no way to extract an infobar from 65 // its owner without deleting it, for reparenting in another tab. 66 void SetOwner(InfoBarService* owner); 67 68 // Makes the infobar visible. If |animate| is true, the infobar is then 69 // animated to full size. 70 void Show(bool animate); 71 72 // Makes the infobar hidden. If |animate| is false, the infobar is 73 // immediately removed from the container, and, if now unowned, deleted. If 74 // |animate| is true, the infobar is animated to zero size, ultimately 75 // triggering a call to AnimationEnded(). 76 void Hide(bool animate); 77 78 // Changes the target height of the arrow portion of the infobar. This has no 79 // effect once the infobar is animating closed. 80 void SetArrowTargetHeight(int height); 81 82 // Notifies the infobar that it is no longer owned and should delete itself 83 // once it is invisible. 84 void CloseSoon(); 85 86 // Forwards a close request to our owner. This is a no-op if we're already 87 // unowned. 88 void RemoveSelf(); 89 90 // Changes the target height of the main ("bar") portion of the infobar. 91 void SetBarTargetHeight(int height); 92 93 const gfx::SlideAnimation& animation() const { return animation_; } 94 int arrow_height() const { return arrow_height_; } 95 int arrow_target_height() const { return arrow_target_height_; } 96 int arrow_half_width() const { return arrow_half_width_; } 97 int total_height() const { return arrow_height_ + bar_height_; } 98 99 protected: 100 // gfx::AnimationDelegate: 101 virtual void AnimationProgressed(const gfx::Animation* animation) OVERRIDE; 102 103 const InfoBarContainer* container() const { return container_; } 104 InfoBarContainer* container() { return container_; } 105 gfx::SlideAnimation* animation() { return &animation_; } 106 int bar_height() const { return bar_height_; } 107 int bar_target_height() const { return bar_target_height_; } 108 109 // Platforms may optionally override these if they need to do work during 110 // processing of the given calls. 111 virtual void PlatformSpecificSetOwner() {} 112 virtual void PlatformSpecificShow(bool animate) {} 113 virtual void PlatformSpecificHide(bool animate) {} 114 virtual void PlatformSpecificOnCloseSoon() {} 115 virtual void PlatformSpecificOnHeightsRecalculated() {} 116 117 private: 118 // gfx::AnimationDelegate: 119 virtual void AnimationEnded(const gfx::Animation* animation) OVERRIDE; 120 121 // Finds the new desired arrow and bar heights, and if they differ from the 122 // current ones, calls PlatformSpecificOnHeightRecalculated(). Informs our 123 // container our state has changed if either the heights have changed or 124 // |force_notify| is set. 125 void RecalculateHeights(bool force_notify); 126 127 // Checks whether the infobar is unowned and done with all animations. If so, 128 // notifies the container that it should remove this infobar, and deletes 129 // itself. 130 void MaybeDelete(); 131 132 InfoBarService* owner_; 133 scoped_ptr<InfoBarDelegate> delegate_; 134 InfoBarContainer* container_; 135 gfx::SlideAnimation animation_; 136 137 // The current and target heights of the arrow and bar portions, and half the 138 // current arrow width. (It's easier to work in half-widths as we draw the 139 // arrow as two halves on either side of a center point.) 140 int arrow_height_; // Includes both fill and top stroke. 141 int arrow_target_height_; 142 int arrow_half_width_; // Includes only fill. 143 int bar_height_; // Includes both fill and bottom separator. 144 int bar_target_height_; 145 146 DISALLOW_COPY_AND_ASSIGN(InfoBar); 147 }; 148 149 #endif // CHROME_BROWSER_INFOBARS_INFOBAR_H_ 150