1// Copyright 2013 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_FRAME_OPAQUE_BROWSER_FRAME_VIEW_LAYOUT_H_
6#define CHROME_BROWSER_UI_VIEWS_FRAME_OPAQUE_BROWSER_FRAME_VIEW_LAYOUT_H_
7
8#include "chrome/browser/ui/views/frame/opaque_browser_frame_view.h"
9#include "ui/views/layout/layout_manager.h"
10#include "ui/views/window/frame_buttons.h"
11
12class AvatarLabel;
13class AvatarMenuButton;
14class NewAvatarButton;
15class OpaqueBrowserFrameViewLayoutDelegate;
16
17namespace views {
18class ImageButton;
19class Label;
20}
21
22// Calculates the position of the widgets in the opaque browser frame view.
23//
24// This is separated out for testing reasons. OpaqueBrowserFrameView has tight
25// dependencies with Browser and classes that depend on Browser.
26class OpaqueBrowserFrameViewLayout : public views::LayoutManager {
27 public:
28  explicit OpaqueBrowserFrameViewLayout(
29      OpaqueBrowserFrameViewLayoutDelegate* delegate);
30  virtual ~OpaqueBrowserFrameViewLayout();
31
32  // Whether we should add the (minimize,maximize,close) buttons. This should be
33  // true if the buttons could be shown at any time in this session (see
34  // OpaqueBrowserFrameViewLayoutDelegate::ShouldShowCaptionButtons for whether
35  // they are currently visible).
36  static bool ShouldAddDefaultCaptionButtons();
37
38  // Configures the button ordering in the frame.
39  void SetButtonOrdering(
40      const std::vector<views::FrameButton>& leading_buttons,
41      const std::vector<views::FrameButton>& trailing_buttons);
42
43  gfx::Rect GetBoundsForTabStrip(
44      const gfx::Size& tabstrip_preferred_size,
45      int available_width) const;
46
47  gfx::Size GetMinimumSize(int available_width) const;
48
49  // Returns the bounds of the window required to display the content area at
50  // the specified bounds.
51  gfx::Rect GetWindowBoundsForClientBounds(
52      const gfx::Rect& client_bounds) const;
53
54  // Returns the thickness of the border that makes up the window frame edges.
55  // This does not include any client edge.  If |restored| is true, acts as if
56  // the window is restored regardless of the real mode.
57  int FrameBorderThickness(bool restored) const;
58
59  // Returns the thickness of the entire nonclient left, right, and bottom
60  // borders, including both the window frame and any client edge.
61  int NonClientBorderThickness() const;
62
63  // Returns the height of the entire nonclient top border, including the window
64  // frame, any title area, and any connected client edge.  If |restored| is
65  // true, acts as if the window is restored regardless of the real mode.
66  int NonClientTopBorderHeight(bool restored) const;
67
68  int GetTabStripInsetsTop(bool restored) const;
69
70  // Returns the y-coordinate of the caption buttons.  If |restored| is true,
71  // acts as if the window is restored regardless of the real mode.
72  int CaptionButtonY(bool restored) const;
73
74  // Returns the thickness of the 3D edge along the bottom of the titlebar.  If
75  // |restored| is true, acts as if the window is restored regardless of the
76  // real mode.
77  int TitlebarBottomThickness(bool restored) const;
78
79  // Returns the bounds of the titlebar icon (or where the icon would be if
80  // there was one).
81  gfx::Rect IconBounds() const;
82
83  // Returns the bounds of the client area for the specified view size.
84  gfx::Rect CalculateClientAreaBounds(int width, int height) const;
85
86  void set_extra_caption_y(int extra_caption_y) {
87    extra_caption_y_ = extra_caption_y;
88  }
89
90  void set_window_caption_spacing(int window_caption_spacing) {
91    window_caption_spacing_ = window_caption_spacing;
92  }
93
94  const gfx::Rect& client_view_bounds() const { return client_view_bounds_; }
95
96  // Determines whether the title bar is condensed vertically, as when the
97  // window is maximized. If true, the title bar is just the height of a tab,
98  // rather than having extra vertical space above the tabs. This also removes
99  // the thick frame border and rounded corners.
100  bool IsTitleBarCondensed() const;
101
102 private:
103  // Whether a specific button should be inserted on the leading or trailing
104  // side.
105  enum ButtonAlignment {
106    ALIGN_LEADING,
107    ALIGN_TRAILING
108  };
109
110  // Determines whether the avatar should be shown on the right side of the tab
111  // strip (instead of the usual left).
112  bool ShouldAvatarBeOnRight() const;
113
114  // Determines the amount of spacing between the New Tab button and the element
115  // to its immediate right.
116  int NewTabCaptionSpacing() const;
117
118  // Layout various sub-components of this view.
119  void LayoutWindowControls(views::View* host);
120  void LayoutTitleBar(views::View* host);
121  void LayoutAvatar(views::View* host);
122  void LayoutNewStyleAvatar(views::View* host);
123
124  void ConfigureButton(views::View* host,
125                       views::FrameButton button_id,
126                       ButtonAlignment align,
127                       int caption_y);
128
129  // Sets the visibility of all buttons associated with |button_id| to false.
130  void HideButton(views::FrameButton button_id);
131
132  // Adds a window caption button to either the leading or trailing side.
133  void SetBoundsForButton(views::View* host,
134                          views::ImageButton* button,
135                          ButtonAlignment align,
136                          int caption_y);
137
138  // Internal implementation of ViewAdded() and ViewRemoved().
139  void SetView(int id, views::View* view);
140
141  // Overriden from views::LayoutManager:
142  virtual void Layout(views::View* host) OVERRIDE;
143  virtual gfx::Size GetPreferredSize(const views::View* host) const OVERRIDE;
144  virtual void ViewAdded(views::View* host, views::View* view) OVERRIDE;
145  virtual void ViewRemoved(views::View* host, views::View* view) OVERRIDE;
146
147  OpaqueBrowserFrameViewLayoutDelegate* delegate_;
148
149  // The layout rect of the avatar icon, if visible.
150  gfx::Rect avatar_bounds_;
151
152  // The bounds of the ClientView.
153  gfx::Rect client_view_bounds_;
154
155  // The layout of the window icon, if visible.
156  gfx::Rect window_icon_bounds_;
157
158  // How far from the leading/trailing edge of the view the next window control
159  // should be placed.
160  int leading_button_start_;
161  int trailing_button_start_;
162
163  // The size of the window buttons, and the avatar menu item (if any). This
164  // does not count labels or other elements that should be counted in a
165  // minimal frame.
166  int minimum_size_for_buttons_;
167
168  // Whether any of the window control buttons were packed on the leading.
169  bool has_leading_buttons_;
170  bool has_trailing_buttons_;
171
172  // Extra offset from the top of the frame to the top of the window control
173  // buttons. Configurable based on platform and whether we are under test.
174  int extra_caption_y_;
175
176  // Extra offset between the individual window caption buttons.
177  int window_caption_spacing_;
178
179  // Window controls.
180  views::ImageButton* minimize_button_;
181  views::ImageButton* maximize_button_;
182  views::ImageButton* restore_button_;
183  views::ImageButton* close_button_;
184
185  views::View* window_icon_;
186  views::Label* window_title_;
187
188  AvatarLabel* avatar_label_;
189  AvatarMenuButton* avatar_button_;
190  views::View* new_avatar_button_;
191
192  std::vector<views::FrameButton> leading_buttons_;
193  std::vector<views::FrameButton> trailing_buttons_;
194
195  DISALLOW_COPY_AND_ASSIGN(OpaqueBrowserFrameViewLayout);
196};
197
198#endif  // CHROME_BROWSER_UI_VIEWS_FRAME_OPAQUE_BROWSER_FRAME_VIEW_LAYOUT_H_
199