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_UI_VIEWS_INFOBARS_INFOBAR_VIEW_H_
6 #define CHROME_BROWSER_UI_VIEWS_INFOBARS_INFOBAR_VIEW_H_
7 
8 #include "base/compiler_specific.h"
9 #include "base/macros.h"
10 #include "components/infobars/core/infobar.h"
11 #include "components/infobars/core/infobar_container.h"
12 #include "third_party/skia/include/core/SkPath.h"
13 #include "ui/views/controls/menu/menu_types.h"
14 #include "ui/views/focus/external_focus_tracker.h"
15 #include "ui/views/view.h"
16 
17 namespace views {
18 class ImageButton;
19 class ImageView;
20 class Label;
21 class Link;
22 class MenuRunner;
23 }  // namespace views
24 
25 class InfoBarView : public infobars::InfoBar,
26                     public views::View,
27                     public views::ExternalFocusTracker {
28  public:
29   explicit InfoBarView(std::unique_ptr<infobars::InfoBarDelegate> delegate);
30   ~InfoBarView() override;
31 
32   // Requests that the infobar recompute its target height.
33   void RecalculateHeight();
34 
35   // views::View:
36   void Layout() override;
37   void GetAccessibleNodeData(ui::AXNodeData* node_data) override;
38   gfx::Size CalculatePreferredSize() const override;
39   void ViewHierarchyChanged(
40       const views::ViewHierarchyChangedDetails& details) override;
41   void OnPaint(gfx::Canvas* canvas) override;
42   void OnThemeChanged() override;
43 
44   // views::ExternalFocusTracker:
45   void OnWillChangeFocus(View* focused_before, View* focused_now) override;
46 
47  protected:
48   using Labels = std::vector<views::Label*>;
49 
50   // Creates a label with the appropriate font and color for an infobar.
51   views::Label* CreateLabel(const base::string16& text) const;
52 
53   // Creates a link with the appropriate font and color for an infobar.
54   // NOTE: Subclasses must ignore link clicks if we're unowned.
55   views::Link* CreateLink(const base::string16& text);
56 
57   // Given |views| and the total |available_width| to display them in, sets
58   // each view's size so that the longest view shrinks until it reaches the
59   // length of the next-longest view, then both shrink until reaching the
60   // length of the next-longest, and so forth.
61   static void AssignWidths(Views* views, int available_width);
62 
63   // Returns the minimum width the content (that is, everything between the icon
64   // and the close button) can be shrunk to.  This is used to prevent the close
65   // button from overlapping views that cannot be shrunk any further.
66   virtual int ContentMinimumWidth() const;
67 
68   // These return x coordinates delimiting the usable area for subclasses to lay
69   // out their controls.
70   int StartX() const;
71   int EndX() const;
72 
73   // Given a |view|, returns the centered y position, taking into account
74   // animation so the control "slides in" (or out) as we animate open and
75   // closed.
76   int OffsetY(views::View* view) const;
77 
78   // infobars::InfoBar:
79   void PlatformSpecificShow(bool animate) override;
80   void PlatformSpecificHide(bool animate) override;
81   void PlatformSpecificOnHeightRecalculated() override;
82 
83  private:
84   FRIEND_TEST_ALL_PREFIXES(InfoBarViewTest, ShouldDrawSeparator);
85 
86   // Does the actual work for AssignWidths().  Assumes |views| is sorted by
87   // decreasing preferred width.
88   static void AssignWidthsSorted(Views* views, int available_width);
89 
90   // Returns whether this infobar should draw a 1 px separator at its top.
91   bool ShouldDrawSeparator() const;
92 
93   // Returns how much space the container should reserve for a separator between
94   // infobars, in addition to the height of the infobars themselves.
95   int GetSeparatorHeight() const;
96 
97   // Returns the current color for the theme property |id|.  Will return the
98   // wrong value if no theme provider is available.
99   SkColor GetColor(int id) const;
100 
101   // Sets various attributes on |label| that are common to all child links and
102   // labels.
103   void SetLabelDetails(views::Label* label) const;
104 
105   // Callback used by the link created by CreateLink().
106   void LinkClicked(const ui::Event& event);
107 
108   void CloseButtonPressed();
109 
110   // The optional icon at the left edge of the InfoBar.
111   views::ImageView* icon_ = nullptr;
112 
113   // The close button at the right edge of the InfoBar.
114   views::ImageButton* close_button_ = nullptr;
115 
116   // Used to run the menu.
117   std::unique_ptr<views::MenuRunner> menu_runner_;
118 
119   DISALLOW_COPY_AND_ASSIGN(InfoBarView);
120 };
121 
122 #endif  // CHROME_BROWSER_UI_VIEWS_INFOBARS_INFOBAR_VIEW_H_
123