10529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#ifndef COMPONENTS_INFOBARS_CORE_INFOBAR_H_
60529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#define COMPONENTS_INFOBARS_CORE_INFOBAR_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <utility>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "components/infobars/core/infobar_delegate.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/core/SkColor.h"
13d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/gfx/animation/animation_delegate.h"
14d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/gfx/animation/slide_animation.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/size.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochnamespace infobars {
180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class InfoBarContainer;
20e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochclass InfoBarManager;
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// InfoBar is a cross-platform base class for an infobar "view" (in the MVC
23a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// sense), which owns a corresponding InfoBarDelegate "model".  Typically,
24a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// a caller will call XYZInfoBarDelegate::Create() and pass in the
25e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// InfoBarManager for the relevant tab.  This will create an XYZInfoBarDelegate,
26a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// create a platform-specific subclass of InfoBar to own it, and then call
27e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// InfoBarManager::AddInfoBar() to give it ownership of the infobar.
28a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// During its life, the InfoBar may be shown and hidden as the owning tab is
29e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// switched between the foreground and background.  Eventually, InfoBarManager
30a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// will instruct the InfoBar to close itself.  At this point, the InfoBar will
31a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// optionally animate closed; once it's no longer visible, it deletes itself,
32a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// destroying the InfoBarDelegate in the process.
33a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)//
34a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Thus, InfoBarDelegate and InfoBar implementations can assume they share
35a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// lifetimes, and not NULL-check each other; but if one needs to reach back into
36e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// the owning InfoBarManager, it must check whether that's still possible.
37d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)class InfoBar : public gfx::AnimationDelegate {
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // These are the types passed as Details for infobar-related notifications.
40a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  typedef InfoBar AddedDetails;
41a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  typedef std::pair<InfoBar*, bool> RemovedDetails;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Platforms must define these.
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kDefaultBarTargetHeight;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kSeparatorLineHeight;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kDefaultArrowTargetHeight;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kMaximumArrowTargetHeight;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The half-width (see comments on |arrow_half_width_| below) scales to its
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // default and maximum values proportionally to how the height scales to its.
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kDefaultArrowTargetHalfWidth;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kMaximumArrowTargetHalfWidth;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  explicit InfoBar(scoped_ptr<InfoBarDelegate> delegate);
54a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual ~InfoBar();
55a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static SkColor GetTopColor(InfoBarDelegate::Type infobar_type);
57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  static SkColor GetBottomColor(InfoBarDelegate::Type infobar_type);
58f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
59e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  InfoBarManager* owner() { return owner_; }
60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  InfoBarDelegate* delegate() const { return delegate_.get(); }
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_container(InfoBarContainer* container) { container_ = container; }
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Sets |owner_|.  This also calls StoreActiveEntryUniqueID() on |delegate_|.
64a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // This must only be called once as there's no way to extract an infobar from
65a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // its owner without deleting it, for reparenting in another tab.
66e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  void SetOwner(InfoBarManager* owner);
67a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Makes the infobar visible.  If |animate| is true, the infobar is then
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // animated to full size.
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Show(bool animate);
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Makes the infobar hidden.  If |animate| is false, the infobar is
73a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // immediately removed from the container, and, if now unowned, deleted.  If
74a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // |animate| is true, the infobar is animated to zero size, ultimately
75a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // triggering a call to AnimationEnded().
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Hide(bool animate);
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Changes the target height of the arrow portion of the infobar.  This has no
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // effect once the infobar is animating closed.
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetArrowTargetHeight(int height);
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Notifies the infobar that it is no longer owned and should delete itself
83a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // once it is invisible.
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CloseSoon();
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Forwards a close request to our owner.  This is a no-op if we're already
87a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // unowned.
88a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void RemoveSelf();
89a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
90424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Changes the target height of the main ("bar") portion of the infobar.
91424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void SetBarTargetHeight(int height);
92424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
93d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  const gfx::SlideAnimation& animation() const { return animation_; }
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int arrow_height() const { return arrow_height_; }
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int arrow_target_height() const { return arrow_target_height_; }
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int arrow_half_width() const { return arrow_half_width_; }
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int total_height() const { return arrow_height_ + bar_height_; }
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
100d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // gfx::AnimationDelegate:
101d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  virtual void AnimationProgressed(const gfx::Animation* animation) OVERRIDE;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const InfoBarContainer* container() const { return container_; }
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InfoBarContainer* container() { return container_; }
105d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  gfx::SlideAnimation* animation() { return &animation_; }
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int bar_height() const { return bar_height_; }
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int bar_target_height() const { return bar_target_height_; }
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Platforms may optionally override these if they need to do work during
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // processing of the given calls.
111a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void PlatformSpecificSetOwner() {}
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void PlatformSpecificShow(bool animate) {}
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void PlatformSpecificHide(bool animate) {}
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void PlatformSpecificOnCloseSoon() {}
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void PlatformSpecificOnHeightsRecalculated() {}
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
118d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // gfx::AnimationDelegate:
119d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  virtual void AnimationEnded(const gfx::Animation* animation) OVERRIDE;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Finds the new desired arrow and bar heights, and if they differ from the
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // current ones, calls PlatformSpecificOnHeightRecalculated().  Informs our
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // container our state has changed if either the heights have changed or
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |force_notify| is set.
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RecalculateHeights(bool force_notify);
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
127a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Checks whether the infobar is unowned and done with all animations.  If so,
128a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // notifies the container that it should remove this infobar, and deletes
129a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // itself.
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void MaybeDelete();
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
132e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  InfoBarManager* owner_;
133a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_ptr<InfoBarDelegate> delegate_;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InfoBarContainer* container_;
135d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  gfx::SlideAnimation animation_;
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The current and target heights of the arrow and bar portions, and half the
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // current arrow width.  (It's easier to work in half-widths as we draw the
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // arrow as two halves on either side of a center point.)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int arrow_height_;         // Includes both fill and top stroke.
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int arrow_target_height_;
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int arrow_half_width_;     // Includes only fill.
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int bar_height_;           // Includes both fill and bottom separator.
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int bar_target_height_;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(InfoBar);
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}  // namespace infobars
1500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#endif  // COMPONENTS_INFOBARS_CORE_INFOBAR_H_
152