summaryrefslogtreecommitdiffstats
path: root/chrome/browser/ui/views/infobars/infobar_view.h
blob: 3db74352ad8c2f3407162efa8b9987dd24998016 (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
143
144
145
146
147
148
149
150
151
152
// Copyright (c) 2012 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 CHROME_BROWSER_UI_VIEWS_INFOBARS_INFOBAR_VIEW_H_
#define CHROME_BROWSER_UI_VIEWS_INFOBARS_INFOBAR_VIEW_H_

#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "chrome/browser/infobars/infobar.h"
#include "chrome/browser/infobars/infobar_container.h"
#include "third_party/skia/include/core/SkPath.h"
#include "ui/views/controls/button/button.h"
#include "ui/views/controls/menu/menu_item_view.h"
#include "ui/views/focus/external_focus_tracker.h"

namespace ui {
class MenuModel;
}

namespace views {
class ImageButton;
class ImageView;
class Label;
class LabelButton;
class Link;
class LinkListener;
class MenuButton;
class MenuButtonListener;
class MenuRunner;
}  // namespace views

class InfoBarView : public InfoBar,
                    public views::View,
                    public views::ButtonListener,
                    public views::ExternalFocusTracker {
 public:
  explicit InfoBarView(scoped_ptr<InfoBarDelegate> delegate);

  const SkPath& fill_path() const { return fill_path_; }
  const SkPath& stroke_path() const { return stroke_path_; }

 protected:
  typedef std::vector<views::Label*> Labels;

  static const int kButtonButtonSpacing;
  static const int kEndOfLabelSpacing;

  virtual ~InfoBarView();

  // Creates a label with the appropriate font and color for an infobar.
  views::Label* CreateLabel(const base::string16& text) const;

  // Creates a link with the appropriate font and color for an infobar.
  // NOTE: Subclasses must ignore link clicks if we're unowned.
  views::Link* CreateLink(const base::string16& text,
                          views::LinkListener* listener) const;

  // Creates a menu button with an infobar-specific appearance.
  // NOTE: Subclasses must ignore button presses if we're unowned.
  static views::MenuButton* CreateMenuButton(
      const base::string16& text,
      views::MenuButtonListener* menu_button_listener);

  // Creates a button with an infobar-specific appearance.
  // NOTE: Subclasses must ignore button presses if we're unowned.
  static views::LabelButton* CreateLabelButton(views::ButtonListener* listener,
                                               const base::string16& text,
                                               bool needs_elevation);

  // Given |labels| and the total |available_width| to display them in, sets
  // each label's size so that the longest label shrinks until it reaches the
  // length of the next-longest label, then both shrink until reaching the
  // length of the next-longest, and so forth.
  static void AssignWidths(Labels* labels, int available_width);

  // views::View:
  virtual void Layout() OVERRIDE;
  virtual void ViewHierarchyChanged(
      const ViewHierarchyChangedDetails& details) OVERRIDE;

  // views::ButtonListener:
  // NOTE: This must not be called if we're unowned.  (Subclasses should ignore
  // calls to ButtonPressed() in this case.)
  virtual void ButtonPressed(views::Button* sender,
                             const ui::Event& event) OVERRIDE;

  // Returns the minimum width the content (that is, everything between the icon
  // and the close button) can be shrunk to.  This is used to prevent the close
  // button from overlapping views that cannot be shrunk any further.
  virtual int ContentMinimumWidth();

  // These return x coordinates delimiting the usable area for subclasses to lay
  // out their controls.
  int StartX() const;
  int EndX() const;

  // Given a |view|, returns the centered y position within us, taking into
  // account animation so the control "slides in" (or out) as we animate open
  // and closed.
  int OffsetY(views::View* view) const;

  // Convenience getter.
  const InfoBarContainer::Delegate* container_delegate() const;

  // Shows a menu at the specified position.
  // NOTE: This must not be called if we're unowned.  (Subclasses should ignore
  // calls to RunMenu() in this case.)
  void RunMenuAt(ui::MenuModel* menu_model,
                 views::MenuButton* button,
                 views::MenuItemView::AnchorPosition anchor);

 private:
  static const int kHorizontalPadding;
  static const int kCloseButtonSpacing;

  // Does the actual work for AssignWidths().  Assumes |labels| is sorted by
  // decreasing preferred width.
  static void AssignWidthsSorted(Labels* labels, int available_width);

  // InfoBar:
  virtual void PlatformSpecificShow(bool animate) OVERRIDE;
  virtual void PlatformSpecificHide(bool animate) OVERRIDE;
  virtual void PlatformSpecificOnHeightsRecalculated() OVERRIDE;

  // views::View:
  virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE;
  virtual gfx::Size GetPreferredSize() OVERRIDE;
  virtual void PaintChildren(gfx::Canvas* canvas) OVERRIDE;

  // views::ExternalFocusTracker:
  virtual void OnWillChangeFocus(View* focused_before,
                                 View* focused_now) OVERRIDE;

  // The optional icon at the left edge of the InfoBar.
  views::ImageView* icon_;

  // The close button at the right edge of the InfoBar.
  views::ImageButton* close_button_;

  // The paths for the InfoBarBackground to draw, sized according to the heights
  // above.
  SkPath fill_path_;
  SkPath stroke_path_;

  // Used to run the menu.
  scoped_ptr<views::MenuRunner> menu_runner_;

  DISALLOW_COPY_AND_ASSIGN(InfoBarView);
};

#endif  // CHROME_BROWSER_UI_VIEWS_INFOBARS_INFOBAR_VIEW_H_