summaryrefslogtreecommitdiffstats
path: root/components/infobars/core/infobar.h
blob: f5edd12dade4d23540ea05b3ce6911d9955fa434 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef COMPONENTS_INFOBARS_CORE_INFOBAR_H_
#define COMPONENTS_INFOBARS_CORE_INFOBAR_H_

#include <utility>

#include "base/memory/scoped_ptr.h"
#include "components/infobars/core/infobar_delegate.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/gfx/animation/animation_delegate.h"
#include "ui/gfx/animation/slide_animation.h"
#include "ui/gfx/geometry/size.h"

namespace infobars {

class InfoBarContainer;
class InfoBarManager;

// InfoBar is a cross-platform base class for an infobar "view" (in the MVC
// sense), which owns a corresponding InfoBarDelegate "model".  Typically,
// a caller will call XYZInfoBarDelegate::Create() and pass in the
// InfoBarManager for the relevant tab.  This will create an XYZInfoBarDelegate,
// create a platform-specific subclass of InfoBar to own it, and then call
// InfoBarManager::AddInfoBar() to give it ownership of the infobar.
// During its life, the InfoBar may be shown and hidden as the owning tab is
// switched between the foreground and background.  Eventually, InfoBarManager
// will instruct the InfoBar to close itself.  At this point, the InfoBar will
// optionally animate closed; once it's no longer visible, it deletes itself,
// destroying the InfoBarDelegate in the process.
//
// Thus, InfoBarDelegate and InfoBar implementations can assume they share
// lifetimes, and not NULL-check each other; but if one needs to reach back into
// the owning InfoBarManager, it must check whether that's still possible.
class InfoBar : public gfx::AnimationDelegate {
 public:
  // These are the types passed as Details for infobar-related notifications.
  typedef InfoBar AddedDetails;
  typedef std::pair<InfoBar*, bool> RemovedDetails;

  explicit InfoBar(scoped_ptr<InfoBarDelegate> delegate);
  ~InfoBar() override;

  static SkColor GetTopColor(InfoBarDelegate::Type infobar_type);
  static SkColor GetBottomColor(InfoBarDelegate::Type infobar_type);

  InfoBarManager* owner() { return owner_; }
  InfoBarDelegate* delegate() const { return delegate_.get(); }
  void set_container(InfoBarContainer* container) { container_ = container; }

  // Sets |owner_|.  This also sets the nav entry ID on |delegate_|.  This must
  // only be called once as there's no way to extract an infobar from its owner
  // without deleting it, for reparenting in another tab.
  void SetOwner(InfoBarManager* owner);

  // Makes the infobar visible.  If |animate| is true, the infobar is then
  // animated to full size.
  void Show(bool animate);

  // Makes the infobar hidden.  If |animate| is false, the infobar is
  // immediately removed from the container, and, if now unowned, deleted.  If
  // |animate| is true, the infobar is animated to zero size, ultimately
  // triggering a call to AnimationEnded().
  void Hide(bool animate);

  // Changes the target height of the arrow portion of the infobar.  This has no
  // effect once the infobar is animating closed.
  void SetArrowTargetHeight(int height);

  // Notifies the infobar that it is no longer owned and should delete itself
  // once it is invisible.
  void CloseSoon();

  // Forwards a close request to our owner.  This is a no-op if we're already
  // unowned.
  void RemoveSelf();

  // Changes the target height of the main ("bar") portion of the infobar.
  void SetBarTargetHeight(int height);

  const gfx::SlideAnimation& animation() const { return animation_; }
  int arrow_height() const { return arrow_height_; }
  int arrow_target_height() const { return arrow_target_height_; }
  int arrow_half_width() const { return arrow_half_width_; }
  int total_height() const { return arrow_height_ + bar_height_; }

 protected:
  // gfx::AnimationDelegate:
  void AnimationProgressed(const gfx::Animation* animation) override;

  const InfoBarContainer* container() const { return container_; }
  InfoBarContainer* container() { return container_; }
  gfx::SlideAnimation* animation() { return &animation_; }
  int bar_height() const { return bar_height_; }
  int bar_target_height() const { return bar_target_height_; }

  // Platforms may optionally override these if they need to do work during
  // processing of the given calls.
  virtual void PlatformSpecificSetOwner() {}
  virtual void PlatformSpecificShow(bool animate) {}
  virtual void PlatformSpecificHide(bool animate) {}
  virtual void PlatformSpecificOnCloseSoon() {}
  virtual void PlatformSpecificOnHeightsRecalculated() {}

 private:
  // gfx::AnimationDelegate:
  void AnimationEnded(const gfx::Animation* animation) override;

  // Finds the new desired arrow and bar heights, and if they differ from the
  // current ones, calls PlatformSpecificOnHeightRecalculated().  Informs our
  // container our state has changed if either the heights have changed or
  // |force_notify| is set.
  void RecalculateHeights(bool force_notify);

  // Checks whether the infobar is unowned and done with all animations.  If so,
  // notifies the container that it should remove this infobar, and deletes
  // itself.
  void MaybeDelete();

  InfoBarManager* owner_;
  scoped_ptr<InfoBarDelegate> delegate_;
  InfoBarContainer* container_;
  gfx::SlideAnimation animation_;

  // The current and target heights of the arrow and bar portions, and half the
  // current arrow width.  (It's easier to work in half-widths as we draw the
  // arrow as two halves on either side of a center point.)  All these values
  // scale in unison to the container delegate's default and maximum values.
  int arrow_height_;         // Includes both fill and top stroke.
  int arrow_target_height_;  // Should always be set by the time we read it.
  int arrow_half_width_;     // Includes only fill.
  int bar_height_;           // Includes both fill and bottom separator.
  int bar_target_height_;    // May be left as -1, meaning "use default".

  DISALLOW_COPY_AND_ASSIGN(InfoBar);
};

}  // namespace infobars

#endif  // COMPONENTS_INFOBARS_CORE_INFOBAR_H_