OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/ui/views/frame/opaque_browser_frame_view.h" | 5 #include "chrome/browser/ui/views/frame/opaque_browser_frame_view.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
11 #include "base/compiler_specific.h" | 11 #include "base/compiler_specific.h" |
12 #include "base/prefs/pref_service.h" | 12 #include "base/prefs/pref_service.h" |
13 #include "base/strings/utf_string_conversions.h" | 13 #include "base/strings/utf_string_conversions.h" |
14 #include "chrome/browser/chrome_notification_types.h" | 14 #include "chrome/browser/chrome_notification_types.h" |
15 #include "chrome/browser/themes/theme_properties.h" | 15 #include "chrome/browser/themes/theme_properties.h" |
16 #include "chrome/browser/ui/views/avatar_label.h" | 16 #include "chrome/browser/ui/views/avatar_label.h" |
17 #include "chrome/browser/ui/views/avatar_menu_button.h" | 17 #include "chrome/browser/ui/views/avatar_menu_button.h" |
18 #include "chrome/browser/ui/views/frame/browser_frame.h" | 18 #include "chrome/browser/ui/views/frame/browser_frame.h" |
19 #include "chrome/browser/ui/views/frame/browser_view.h" | 19 #include "chrome/browser/ui/views/frame/browser_view.h" |
20 #include "chrome/browser/ui/views/frame/opaque_browser_frame_view_layout.h" | |
20 #include "chrome/browser/ui/views/tab_icon_view.h" | 21 #include "chrome/browser/ui/views/tab_icon_view.h" |
21 #include "chrome/browser/ui/views/tabs/tab_strip.h" | 22 #include "chrome/browser/ui/views/tabs/tab_strip.h" |
22 #include "chrome/browser/ui/views/toolbar_view.h" | 23 #include "chrome/browser/ui/views/toolbar_view.h" |
23 #include "chrome/common/chrome_switches.h" | 24 #include "chrome/common/chrome_switches.h" |
24 #include "chrome/common/pref_names.h" | 25 #include "chrome/common/pref_names.h" |
25 #include "content/public/browser/notification_service.h" | 26 #include "content/public/browser/notification_service.h" |
26 #include "content/public/browser/web_contents.h" | 27 #include "content/public/browser/web_contents.h" |
27 #include "grit/chromium_strings.h" | 28 #include "grit/chromium_strings.h" |
28 #include "grit/generated_resources.h" | 29 #include "grit/generated_resources.h" |
29 #include "grit/theme_resources.h" | 30 #include "grit/theme_resources.h" |
30 #include "grit/ui_resources.h" | 31 #include "grit/ui_resources.h" |
31 #include "ui/base/accessibility/accessible_view_state.h" | 32 #include "ui/base/accessibility/accessible_view_state.h" |
32 #include "ui/base/hit_test.h" | 33 #include "ui/base/hit_test.h" |
33 #include "ui/base/l10n/l10n_util.h" | 34 #include "ui/base/l10n/l10n_util.h" |
34 #include "ui/base/resource/resource_bundle.h" | 35 #include "ui/base/resource/resource_bundle.h" |
35 #include "ui/base/theme_provider.h" | 36 #include "ui/base/theme_provider.h" |
36 #include "ui/gfx/canvas.h" | 37 #include "ui/gfx/canvas.h" |
37 #include "ui/gfx/font.h" | 38 #include "ui/gfx/font.h" |
38 #include "ui/gfx/image/image.h" | 39 #include "ui/gfx/image/image.h" |
39 #include "ui/gfx/image/image_skia.h" | 40 #include "ui/gfx/image/image_skia.h" |
40 #include "ui/gfx/path.h" | 41 #include "ui/gfx/path.h" |
41 #include "ui/views/controls/button/image_button.h" | 42 #include "ui/views/controls/button/image_button.h" |
42 #include "ui/views/controls/image_view.h" | 43 #include "ui/views/controls/image_view.h" |
43 #include "ui/views/controls/label.h" | 44 #include "ui/views/controls/label.h" |
44 #include "ui/views/layout/layout_constants.h" | 45 #include "ui/views/layout/layout_constants.h" |
45 #include "ui/views/widget/root_view.h" | 46 #include "ui/views/widget/root_view.h" |
46 #include "ui/views/window/frame_background.h" | 47 #include "ui/views/window/frame_background.h" |
47 #include "ui/views/window/window_shape.h" | 48 #include "ui/views/window/window_shape.h" |
48 | 49 |
49 #if defined(OS_WIN) | |
50 #include "win8/util/win8_util.h" | |
51 #endif // OS_WIN | |
52 | |
53 using content::WebContents; | 50 using content::WebContents; |
54 | 51 |
55 namespace { | 52 namespace { |
56 | 53 |
57 // The frame border is only visible in restored mode and is hardcoded to 4 px on | |
58 // each side regardless of the system window border size. | |
59 const int kFrameBorderThickness = 4; | |
60 // Besides the frame border, there's another 9 px of empty space atop the | |
61 // window in restored mode, to use to drag the window around. | |
62 const int kNonClientRestoredExtraThickness = 9; | |
63 // While resize areas on Windows are normally the same size as the window | 54 // While resize areas on Windows are normally the same size as the window |
64 // borders, our top area is shrunk by 1 px to make it easier to move the window | 55 // borders, our top area is shrunk by 1 px to make it easier to move the window |
65 // around with our thinner top grabbable strip. (Incidentally, our side and | 56 // around with our thinner top grabbable strip. (Incidentally, our side and |
66 // bottom resize areas don't match the frame border thickness either -- they | 57 // bottom resize areas don't match the frame border thickness either -- they |
67 // span the whole nonclient area, so there's no "dead zone" for the mouse.) | 58 // span the whole nonclient area, so there's no "dead zone" for the mouse.) |
68 const int kTopResizeAdjust = 1; | 59 const int kTopResizeAdjust = 1; |
60 | |
69 // In the window corners, the resize areas don't actually expand bigger, but the | 61 // In the window corners, the resize areas don't actually expand bigger, but the |
70 // 16 px at the end of each edge triggers diagonal resizing. | 62 // 16 px at the end of each edge triggers diagonal resizing. |
71 const int kResizeAreaCornerSize = 16; | 63 const int kResizeAreaCornerSize = 16; |
72 // The titlebar never shrinks too short to show the caption button plus some | 64 |
73 // padding below it. | |
74 const int kCaptionButtonHeightWithPadding = 19; | |
75 // The content left/right images have a shadow built into them. | 65 // The content left/right images have a shadow built into them. |
76 const int kContentEdgeShadowThickness = 2; | 66 const int kContentEdgeShadowThickness = 2; |
77 // The titlebar has a 2 px 3D edge along the top and bottom. | 67 |
78 const int kTitlebarTopAndBottomEdgeThickness = 2; | |
79 // The icon is inset 2 px from the left frame border. | |
80 const int kIconLeftSpacing = 2; | |
81 // The icon never shrinks below 16 px on a side. | 68 // The icon never shrinks below 16 px on a side. |
82 const int kIconMinimumSize = 16; | 69 const int kIconMinimumSize = 16; |
83 // There is a 4 px gap between the icon and the title text. | 70 |
84 const int kIconTitleSpacing = 4; | |
85 // There is a 5 px gap between the title text and the caption buttons. | |
86 const int kTitleLogoSpacing = 5; | |
87 // The avatar ends 2 px above the bottom of the tabstrip (which, given the | |
88 // way the tabstrip draws its bottom edge, will appear like a 1 px gap to the | |
89 // user). | |
90 const int kAvatarBottomSpacing = 2; | |
91 // Space between the frame border and the left edge of the avatar. | |
92 const int kAvatarLeftSpacing = 2; | |
93 // Space between the right edge of the avatar and the tabstrip. | |
94 const int kAvatarRightSpacing = -2; | |
95 // The top 3 px of the tabstrip is shadow; in maximized mode we push this off | 71 // The top 3 px of the tabstrip is shadow; in maximized mode we push this off |
96 // the top of the screen so the tabs appear flush against the screen edge. | 72 // the top of the screen so the tabs appear flush against the screen edge. |
97 const int kTabstripTopShadowThickness = 3; | 73 const int kTabstripTopShadowThickness = 3; |
98 // In restored mode, the New Tab button isn't at the same height as the caption | |
99 // buttons, but the space will look cluttered if it actually slides under them, | |
100 // so we stop it when the gap between the two is down to 5 px. | |
101 const int kNewTabCaptionRestoredSpacing = 5; | |
102 // In maximized mode, where the New Tab button and the caption buttons are at | |
103 // similar vertical coordinates, we need to reserve a larger, 16 px gap to avoid | |
104 // looking too cluttered. | |
105 const int kNewTabCaptionMaximizedSpacing = 16; | |
106 // How far to indent the tabstrip from the left side of the screen when there | |
107 // is no avatar icon. | |
108 const int kTabStripIndent = -6; | |
109 | 74 |
110 // Converts |bounds| from |src|'s coordinate system to |dst|, and checks if | 75 // Converts |bounds| from |src|'s coordinate system to |dst|, and checks if |
111 // |pt| is contained within. | 76 // |pt| is contained within. |
112 bool ConvertedContainsCheck(gfx::Rect bounds, const views::View* src, | 77 bool ConvertedContainsCheck(gfx::Rect bounds, const views::View* src, |
113 const views::View* dst, const gfx::Point& pt) { | 78 const views::View* dst, const gfx::Point& pt) { |
114 DCHECK(src); | 79 DCHECK(src); |
115 DCHECK(dst); | 80 DCHECK(dst); |
116 gfx::Point origin(bounds.origin()); | 81 gfx::Point origin(bounds.origin()); |
117 views::View::ConvertPointToTarget(src, dst, &origin); | 82 views::View::ConvertPointToTarget(src, dst, &origin); |
118 bounds.set_origin(origin); | 83 bounds.set_origin(origin); |
119 return bounds.Contains(pt); | 84 return bounds.Contains(pt); |
120 } | 85 } |
121 | 86 |
122 bool ShouldAddDefaultCaptionButtons() { | |
123 #if defined(OS_WIN) | |
124 return !win8::IsSingleWindowMetroMode(); | |
125 #endif // OS_WIN | |
126 return true; | |
127 } | |
128 | |
129 } // namespace | 87 } // namespace |
130 | 88 |
131 /////////////////////////////////////////////////////////////////////////////// | 89 /////////////////////////////////////////////////////////////////////////////// |
132 // OpaqueBrowserFrameView, public: | 90 // OpaqueBrowserFrameView, public: |
133 | 91 |
134 OpaqueBrowserFrameView::OpaqueBrowserFrameView(BrowserFrame* frame, | 92 OpaqueBrowserFrameView::OpaqueBrowserFrameView(BrowserFrame* frame, |
135 BrowserView* browser_view) | 93 BrowserView* browser_view) |
136 : BrowserNonClientFrameView(frame, browser_view), | 94 : BrowserNonClientFrameView(frame, browser_view), |
95 layout_(new OpaqueBrowserFrameViewLayout(this)), | |
137 minimize_button_(NULL), | 96 minimize_button_(NULL), |
138 maximize_button_(NULL), | 97 maximize_button_(NULL), |
139 restore_button_(NULL), | 98 restore_button_(NULL), |
140 close_button_(NULL), | 99 close_button_(NULL), |
141 window_icon_(NULL), | 100 window_icon_(NULL), |
142 window_title_(NULL), | 101 window_title_(NULL), |
143 frame_background_(new views::FrameBackground()) { | 102 frame_background_(new views::FrameBackground()) { |
144 if (ShouldAddDefaultCaptionButtons()) { | 103 SetLayoutManager(layout_); |
104 | |
105 if (OpaqueBrowserFrameViewLayout::ShouldAddDefaultCaptionButtons()) { | |
145 minimize_button_ = InitWindowCaptionButton(IDR_MINIMIZE, | 106 minimize_button_ = InitWindowCaptionButton(IDR_MINIMIZE, |
146 IDR_MINIMIZE_H, | 107 IDR_MINIMIZE_H, |
147 IDR_MINIMIZE_P, | 108 IDR_MINIMIZE_P, |
148 IDR_MINIMIZE_BUTTON_MASK, | 109 IDR_MINIMIZE_BUTTON_MASK, |
149 IDS_ACCNAME_MINIMIZE); | 110 IDS_ACCNAME_MINIMIZE, |
111 VIEW_ID_MINIMIZE_BUTTON); | |
150 maximize_button_ = InitWindowCaptionButton(IDR_MAXIMIZE, | 112 maximize_button_ = InitWindowCaptionButton(IDR_MAXIMIZE, |
151 IDR_MAXIMIZE_H, | 113 IDR_MAXIMIZE_H, |
152 IDR_MAXIMIZE_P, | 114 IDR_MAXIMIZE_P, |
153 IDR_MAXIMIZE_BUTTON_MASK, | 115 IDR_MAXIMIZE_BUTTON_MASK, |
154 IDS_ACCNAME_MAXIMIZE); | 116 IDS_ACCNAME_MAXIMIZE, |
117 VIEW_ID_MAXIMIZE_BUTTON); | |
155 restore_button_ = InitWindowCaptionButton(IDR_RESTORE, | 118 restore_button_ = InitWindowCaptionButton(IDR_RESTORE, |
156 IDR_RESTORE_H, | 119 IDR_RESTORE_H, |
157 IDR_RESTORE_P, | 120 IDR_RESTORE_P, |
158 IDR_RESTORE_BUTTON_MASK, | 121 IDR_RESTORE_BUTTON_MASK, |
159 IDS_ACCNAME_RESTORE); | 122 IDS_ACCNAME_RESTORE, |
123 VIEW_ID_RESTORE_BUTTON); | |
160 close_button_ = InitWindowCaptionButton(IDR_CLOSE, | 124 close_button_ = InitWindowCaptionButton(IDR_CLOSE, |
161 IDR_CLOSE_H, | 125 IDR_CLOSE_H, |
162 IDR_CLOSE_P, | 126 IDR_CLOSE_P, |
163 IDR_CLOSE_BUTTON_MASK, | 127 IDR_CLOSE_BUTTON_MASK, |
164 IDS_ACCNAME_CLOSE); | 128 IDS_ACCNAME_CLOSE, |
129 VIEW_ID_CLOSE_BUTTON); | |
165 } | 130 } |
166 | 131 |
167 // Initializing the TabIconView is expensive, so only do it if we need to. | 132 // Initializing the TabIconView is expensive, so only do it if we need to. |
168 if (browser_view->ShouldShowWindowIcon()) { | 133 if (browser_view->ShouldShowWindowIcon()) { |
169 window_icon_ = new TabIconView(this); | 134 window_icon_ = new TabIconView(this); |
170 window_icon_->set_is_light(true); | 135 window_icon_->set_is_light(true); |
136 window_icon_->set_id(VIEW_ID_WINDOW_ICON); | |
171 AddChildView(window_icon_); | 137 AddChildView(window_icon_); |
172 window_icon_->Update(); | 138 window_icon_->Update(); |
173 } | 139 } |
174 | 140 |
175 window_title_ = new views::Label(browser_view->GetWindowTitle(), | 141 window_title_ = new views::Label(browser_view->GetWindowTitle(), |
176 BrowserFrame::GetTitleFont()); | 142 BrowserFrame::GetTitleFont()); |
177 window_title_->SetVisible(browser_view->ShouldShowWindowTitle()); | 143 window_title_->SetVisible(browser_view->ShouldShowWindowTitle()); |
178 window_title_->SetEnabledColor(SK_ColorWHITE); | 144 window_title_->SetEnabledColor(SK_ColorWHITE); |
179 // TODO(msw): Use a transparent background color as a workaround to use the | 145 // TODO(msw): Use a transparent background color as a workaround to use the |
180 // gfx::Canvas::NO_SUBPIXEL_RENDERING flag and avoid some visual artifacts. | 146 // gfx::Canvas::NO_SUBPIXEL_RENDERING flag and avoid some visual artifacts. |
181 window_title_->SetBackgroundColor(0x00000000); | 147 window_title_->SetBackgroundColor(0x00000000); |
182 window_title_->SetHorizontalAlignment(gfx::ALIGN_LEFT); | 148 window_title_->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
149 window_title_->set_id(VIEW_ID_WINDOW_TITLE); | |
183 AddChildView(window_title_); | 150 AddChildView(window_title_); |
184 | 151 |
185 UpdateAvatarInfo(); | 152 UpdateAvatarInfo(); |
186 if (!browser_view->IsOffTheRecord()) { | 153 if (!browser_view->IsOffTheRecord()) { |
187 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED, | 154 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED, |
188 content::NotificationService::AllSources()); | 155 content::NotificationService::AllSources()); |
189 } | 156 } |
190 } | 157 } |
191 | 158 |
192 OpaqueBrowserFrameView::~OpaqueBrowserFrameView() { | 159 OpaqueBrowserFrameView::~OpaqueBrowserFrameView() { |
193 } | 160 } |
194 | 161 |
195 /////////////////////////////////////////////////////////////////////////////// | 162 /////////////////////////////////////////////////////////////////////////////// |
196 // OpaqueBrowserFrameView, protected: | |
197 | |
198 int OpaqueBrowserFrameView::GetReservedHeight() const { | |
199 return 0; | |
200 } | |
201 | |
202 gfx::Rect OpaqueBrowserFrameView::GetBoundsForReservedArea() const { | |
203 gfx::Rect client_view_bounds = CalculateClientAreaBounds(width(), height()); | |
204 return gfx::Rect( | |
205 client_view_bounds.x(), | |
206 client_view_bounds.y() + client_view_bounds.height(), | |
207 client_view_bounds.width(), | |
208 GetReservedHeight()); | |
209 } | |
210 | |
211 int OpaqueBrowserFrameView::NonClientTopBorderHeight( | |
212 bool restored) const { | |
213 views::WidgetDelegate* delegate = frame()->widget_delegate(); | |
214 // |delegate| may be NULL if called from callback of InputMethodChanged while | |
215 // a window is being destroyed. | |
216 // See more discussion at http://crosbug.com/8958 | |
217 if (delegate && delegate->ShouldShowWindowTitle()) { | |
218 return std::max(FrameBorderThickness(restored) + IconSize(), | |
219 CaptionButtonY(restored) + kCaptionButtonHeightWithPadding) + | |
220 TitlebarBottomThickness(restored); | |
221 } | |
222 | |
223 return FrameBorderThickness(restored) - | |
224 ((browser_view()->IsTabStripVisible() && | |
225 !restored && !frame()->ShouldLeaveOffsetNearTopBorder()) | |
226 ? kTabstripTopShadowThickness : 0); | |
227 } | |
228 | |
229 /////////////////////////////////////////////////////////////////////////////// | |
230 // OpaqueBrowserFrameView, BrowserNonClientFrameView implementation: | 163 // OpaqueBrowserFrameView, BrowserNonClientFrameView implementation: |
231 | 164 |
232 gfx::Rect OpaqueBrowserFrameView::GetBoundsForTabStrip( | 165 gfx::Rect OpaqueBrowserFrameView::GetBoundsForTabStrip( |
233 views::View* tabstrip) const { | 166 views::View* tabstrip) const { |
234 if (!tabstrip) | 167 if (!tabstrip) |
235 return gfx::Rect(); | 168 return gfx::Rect(); |
236 | 169 |
237 gfx::Rect bounds = GetBoundsForTabStripAndAvatarArea(tabstrip); | 170 return layout_->GetBoundsForTabStrip(tabstrip->GetPreferredSize(), width()); |
238 int space_left_of_tabstrip = kTabStripIndent; | |
239 if (browser_view()->ShouldShowAvatar()) { | |
240 if (avatar_label() && avatar_label()->bounds().width()) { | |
241 // Space between the right edge of the avatar label and the tabstrip. | |
242 const int kAvatarLabelRightSpacing = -10; | |
243 space_left_of_tabstrip = | |
244 avatar_label()->bounds().right() + kAvatarLabelRightSpacing; | |
245 } else { | |
246 space_left_of_tabstrip = | |
247 kAvatarLeftSpacing + avatar_bounds_.width() + kAvatarRightSpacing; | |
248 } | |
249 } | |
250 bounds.Inset(space_left_of_tabstrip, 0, 0, 0); | |
251 return bounds; | |
252 } | 171 } |
253 | 172 |
254 BrowserNonClientFrameView::TabStripInsets | 173 BrowserNonClientFrameView::TabStripInsets |
255 OpaqueBrowserFrameView::GetTabStripInsets(bool restored) const { | 174 OpaqueBrowserFrameView::GetTabStripInsets(bool restored) const { |
256 int top = NonClientTopBorderHeight(restored) + ((!restored && | |
257 (!frame()->ShouldLeaveOffsetNearTopBorder() || | |
258 frame()->IsFullscreen())) ? | |
259 0 : kNonClientRestoredExtraThickness); | |
260 // TODO: include OTR and caption. | 175 // TODO: include OTR and caption. |
261 return TabStripInsets(top, 0, 0); | 176 return TabStripInsets(layout_->GetTabStripInsetsTop(restored), 0, 0); |
262 } | 177 } |
263 | 178 |
264 int OpaqueBrowserFrameView::GetThemeBackgroundXInset() const { | 179 int OpaqueBrowserFrameView::GetThemeBackgroundXInset() const { |
265 return 0; | 180 return 0; |
266 } | 181 } |
267 | 182 |
268 void OpaqueBrowserFrameView::UpdateThrobber(bool running) { | 183 void OpaqueBrowserFrameView::UpdateThrobber(bool running) { |
269 if (window_icon_) | 184 if (window_icon_) |
270 window_icon_->Update(); | 185 window_icon_->Update(); |
271 } | 186 } |
272 | 187 |
273 gfx::Size OpaqueBrowserFrameView::GetMinimumSize() { | 188 gfx::Size OpaqueBrowserFrameView::GetMinimumSize() { |
274 gfx::Size min_size(browser_view()->GetMinimumSize()); | 189 return layout_->GetMinimumSize(width()); |
275 int border_thickness = NonClientBorderThickness(); | |
276 min_size.Enlarge(2 * border_thickness, | |
277 NonClientTopBorderHeight(false) + border_thickness); | |
278 | |
279 views::WidgetDelegate* delegate = frame()->widget_delegate(); | |
280 int min_titlebar_width = (2 * FrameBorderThickness(false)) + | |
281 kIconLeftSpacing + | |
282 (delegate && delegate->ShouldShowWindowIcon() ? | |
283 (IconSize() + kTitleLogoSpacing) : 0); | |
284 #if !defined(OS_CHROMEOS) | |
sky
2013/08/30 16:35:18
It looks like you nuked this in the new code. Inte
Elliot Glaysher
2013/08/30 17:55:01
Intentional, and I had to do some history diving t
| |
285 if (ShouldAddDefaultCaptionButtons()) { | |
286 min_titlebar_width += | |
287 minimize_button_->GetMinimumSize().width() + | |
288 restore_button_->GetMinimumSize().width() + | |
289 close_button_->GetMinimumSize().width(); | |
290 } | |
291 #endif | |
292 min_size.set_width(std::max(min_size.width(), min_titlebar_width)); | |
293 | |
294 // Ensure that the minimum width is enough to hold a minimum width tab strip | |
295 // and avatar icon at their usual insets. | |
296 if (browser_view()->IsTabStripVisible()) { | |
297 TabStrip* tabstrip = browser_view()->tabstrip(); | |
298 const int min_tabstrip_width = tabstrip->GetMinimumSize().width(); | |
299 const int min_tabstrip_area_width = | |
300 width() - GetBoundsForTabStripAndAvatarArea(tabstrip).width() + | |
301 min_tabstrip_width + browser_view()->GetOTRAvatarIcon().width() + | |
302 kAvatarLeftSpacing + kAvatarRightSpacing; | |
303 min_size.set_width(std::max(min_size.width(), min_tabstrip_area_width)); | |
304 } | |
305 | |
306 return min_size; | |
307 } | 190 } |
308 | 191 |
309 /////////////////////////////////////////////////////////////////////////////// | 192 /////////////////////////////////////////////////////////////////////////////// |
310 // OpaqueBrowserFrameView, views::NonClientFrameView implementation: | 193 // OpaqueBrowserFrameView, views::NonClientFrameView implementation: |
311 | 194 |
312 gfx::Rect OpaqueBrowserFrameView::GetBoundsForClientView() const { | 195 gfx::Rect OpaqueBrowserFrameView::GetBoundsForClientView() const { |
313 return client_view_bounds_; | 196 return layout_->client_view_bounds(); |
314 } | 197 } |
315 | 198 |
316 gfx::Rect OpaqueBrowserFrameView::GetWindowBoundsForClientBounds( | 199 gfx::Rect OpaqueBrowserFrameView::GetWindowBoundsForClientBounds( |
317 const gfx::Rect& client_bounds) const { | 200 const gfx::Rect& client_bounds) const { |
318 int top_height = NonClientTopBorderHeight(false); | 201 return layout_->GetWindowBoundsForClientBounds(client_bounds); |
319 int border_thickness = NonClientBorderThickness(); | |
320 return gfx::Rect(std::max(0, client_bounds.x() - border_thickness), | |
321 std::max(0, client_bounds.y() - top_height), | |
322 client_bounds.width() + (2 * border_thickness), | |
323 client_bounds.height() + top_height + border_thickness); | |
324 } | 202 } |
325 | 203 |
326 int OpaqueBrowserFrameView::NonClientHitTest(const gfx::Point& point) { | 204 int OpaqueBrowserFrameView::NonClientHitTest(const gfx::Point& point) { |
327 if (!bounds().Contains(point)) | 205 if (!bounds().Contains(point)) |
328 return HTNOWHERE; | 206 return HTNOWHERE; |
329 | 207 |
330 // See if the point is within the avatar menu button or within the avatar | 208 // See if the point is within the avatar menu button or within the avatar |
331 // label. | 209 // label. |
332 if ((avatar_button() && | 210 if ((avatar_button() && |
333 avatar_button()->GetMirroredBounds().Contains(point)) || | 211 avatar_button()->GetMirroredBounds().Contains(point)) || |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
380 gfx::Path* window_mask) { | 258 gfx::Path* window_mask) { |
381 DCHECK(window_mask); | 259 DCHECK(window_mask); |
382 | 260 |
383 if (frame()->IsMaximized() || frame()->IsFullscreen()) | 261 if (frame()->IsMaximized() || frame()->IsFullscreen()) |
384 return; | 262 return; |
385 | 263 |
386 views::GetDefaultWindowMask(size, window_mask); | 264 views::GetDefaultWindowMask(size, window_mask); |
387 } | 265 } |
388 | 266 |
389 void OpaqueBrowserFrameView::ResetWindowControls() { | 267 void OpaqueBrowserFrameView::ResetWindowControls() { |
390 if (!ShouldAddDefaultCaptionButtons()) | 268 if (!OpaqueBrowserFrameViewLayout::ShouldAddDefaultCaptionButtons()) |
391 return; | 269 return; |
392 restore_button_->SetState(views::CustomButton::STATE_NORMAL); | 270 restore_button_->SetState(views::CustomButton::STATE_NORMAL); |
393 minimize_button_->SetState(views::CustomButton::STATE_NORMAL); | 271 minimize_button_->SetState(views::CustomButton::STATE_NORMAL); |
394 maximize_button_->SetState(views::CustomButton::STATE_NORMAL); | 272 maximize_button_->SetState(views::CustomButton::STATE_NORMAL); |
395 // The close button isn't affected by this constraint. | 273 // The close button isn't affected by this constraint. |
396 } | 274 } |
397 | 275 |
398 void OpaqueBrowserFrameView::UpdateWindowIcon() { | 276 void OpaqueBrowserFrameView::UpdateWindowIcon() { |
399 window_icon_->SchedulePaint(); | 277 window_icon_->SchedulePaint(); |
400 } | 278 } |
(...skipping 22 matching lines...) Expand all Loading... | |
423 * alpha-blend either (since the Windows text APIs don't really do this). | 301 * alpha-blend either (since the Windows text APIs don't really do this). |
424 * So we'd need to sample the background color at the right location and | 302 * So we'd need to sample the background color at the right location and |
425 * synthesize a good shadow color. */ | 303 * synthesize a good shadow color. */ |
426 | 304 |
427 if (browser_view()->IsToolbarVisible()) | 305 if (browser_view()->IsToolbarVisible()) |
428 PaintToolbarBackground(canvas); | 306 PaintToolbarBackground(canvas); |
429 if (!frame()->IsMaximized()) | 307 if (!frame()->IsMaximized()) |
430 PaintRestoredClientEdge(canvas); | 308 PaintRestoredClientEdge(canvas); |
431 } | 309 } |
432 | 310 |
433 void OpaqueBrowserFrameView::Layout() { | |
434 LayoutWindowControls(); | |
435 LayoutTitleBar(); | |
436 LayoutAvatar(); | |
437 client_view_bounds_ = CalculateClientAreaBounds(width(), height()); | |
438 } | |
439 | |
440 bool OpaqueBrowserFrameView::HitTestRect(const gfx::Rect& rect) const { | 311 bool OpaqueBrowserFrameView::HitTestRect(const gfx::Rect& rect) const { |
441 if (!views::View::HitTestRect(rect)) { | 312 if (!views::View::HitTestRect(rect)) { |
442 // |rect| is outside OpaqueBrowserFrameView's bounds. | 313 // |rect| is outside OpaqueBrowserFrameView's bounds. |
443 return false; | 314 return false; |
444 } | 315 } |
445 | 316 |
446 // If the rect is outside the bounds of the client area, claim it. | 317 // If the rect is outside the bounds of the client area, claim it. |
447 // TODO(tdanderson): Implement View::ConvertRectToTarget(). | 318 // TODO(tdanderson): Implement View::ConvertRectToTarget(). |
448 gfx::Point rect_in_client_view_coords_origin(rect.origin()); | 319 gfx::Point rect_in_client_view_coords_origin(rect.origin()); |
449 View::ConvertPointToTarget(this, frame()->client_view(), | 320 View::ConvertPointToTarget(this, frame()->client_view(), |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
552 case chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED: | 423 case chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED: |
553 UpdateAvatarInfo(); | 424 UpdateAvatarInfo(); |
554 break; | 425 break; |
555 default: | 426 default: |
556 NOTREACHED() << "Got a notification we didn't register for!"; | 427 NOTREACHED() << "Got a notification we didn't register for!"; |
557 break; | 428 break; |
558 } | 429 } |
559 } | 430 } |
560 | 431 |
561 /////////////////////////////////////////////////////////////////////////////// | 432 /////////////////////////////////////////////////////////////////////////////// |
433 // OpaqueBrowserFrameView, OpaqueBrowserFrameViewLayoutDelegate implementation: | |
434 | |
435 bool OpaqueBrowserFrameView::ShouldShowWindowIcon() const { | |
436 views::WidgetDelegate* delegate = frame()->widget_delegate(); | |
437 return delegate && delegate->ShouldShowWindowIcon(); | |
438 } | |
439 | |
440 bool OpaqueBrowserFrameView::ShouldShowWindowTitle() const { | |
441 // |delegate| may be NULL if called from callback of InputMethodChanged while | |
442 // a window is being destroyed. | |
443 // See more discussion at http://crosbug.com/8958 | |
444 views::WidgetDelegate* delegate = frame()->widget_delegate(); | |
445 return delegate && delegate->ShouldShowWindowTitle(); | |
446 } | |
447 | |
448 string16 OpaqueBrowserFrameView::GetWindowTitle() const { | |
449 return frame()->widget_delegate()->GetWindowTitle(); | |
450 } | |
451 | |
452 int OpaqueBrowserFrameView::GetIconSize() const { | |
453 #if defined(OS_WIN) | |
454 // This metric scales up if either the titlebar height or the titlebar font | |
455 // size are increased. | |
456 return GetSystemMetrics(SM_CYSMICON); | |
457 #else | |
458 return std::max(BrowserFrame::GetTitleFont().GetHeight(), kIconMinimumSize); | |
459 #endif | |
460 } | |
461 | |
462 bool OpaqueBrowserFrameView::ShouldLeaveOffsetNearTopBorder() const { | |
463 return frame()->ShouldLeaveOffsetNearTopBorder(); | |
464 } | |
465 | |
466 gfx::Size OpaqueBrowserFrameView::GetBrowserViewMinimumSize() const { | |
467 return browser_view()->GetMinimumSize(); | |
468 } | |
469 | |
470 bool OpaqueBrowserFrameView::ShouldShowAvatar() const { | |
471 return browser_view()->ShouldShowAvatar(); | |
472 } | |
473 | |
474 gfx::ImageSkia OpaqueBrowserFrameView::GetOTRAvatarIcon() const { | |
475 return browser_view()->GetOTRAvatarIcon(); | |
476 } | |
477 | |
478 bool OpaqueBrowserFrameView::IsMaximized() const { | |
479 return frame()->IsMaximized(); | |
480 } | |
481 | |
482 bool OpaqueBrowserFrameView::IsMinimized() const { | |
483 return frame()->IsMinimized(); | |
484 } | |
485 | |
486 bool OpaqueBrowserFrameView::IsFullscreen() const { | |
487 return frame()->IsFullscreen(); | |
488 } | |
489 | |
490 bool OpaqueBrowserFrameView::IsTabStripVisible() const { | |
491 return browser_view()->IsTabStripVisible(); | |
492 } | |
493 | |
494 int OpaqueBrowserFrameView::GetTabStripHeight() const { | |
495 return browser_view()->GetTabStripHeight(); | |
496 } | |
497 | |
498 int OpaqueBrowserFrameView::GetAdditionalReservedSpaceInTabStrip() const { | |
499 // We don't have the sysmenu buttons in Windows 8 metro mode. However there | |
500 // are buttons like the window switcher which are drawn in the non client | |
501 // are in the BrowserView. We need to ensure that the tab strip does not | |
502 // draw on the window switcher button. | |
503 views::View* button = browser_view()->window_switcher_button(); | |
504 return button ? button->width() : 0; | |
505 } | |
506 | |
507 gfx::Size OpaqueBrowserFrameView::GetTabstripPreferredSize() const { | |
508 gfx::Size s = browser_view()->tabstrip()->GetPreferredSize(); | |
509 return s; | |
510 } | |
511 | |
512 /////////////////////////////////////////////////////////////////////////////// | |
562 // OpaqueBrowserFrameView, private: | 513 // OpaqueBrowserFrameView, private: |
563 | 514 |
564 views::ImageButton* OpaqueBrowserFrameView::InitWindowCaptionButton( | 515 views::ImageButton* OpaqueBrowserFrameView::InitWindowCaptionButton( |
565 int normal_image_id, | 516 int normal_image_id, |
566 int hot_image_id, | 517 int hot_image_id, |
567 int pushed_image_id, | 518 int pushed_image_id, |
568 int mask_image_id, | 519 int mask_image_id, |
569 int accessibility_string_id) { | 520 int accessibility_string_id, |
521 ViewID view_id) { | |
570 views::ImageButton* button = new views::ImageButton(this); | 522 views::ImageButton* button = new views::ImageButton(this); |
571 ui::ThemeProvider* tp = frame()->GetThemeProvider(); | 523 ui::ThemeProvider* tp = frame()->GetThemeProvider(); |
572 button->SetImage(views::CustomButton::STATE_NORMAL, | 524 button->SetImage(views::CustomButton::STATE_NORMAL, |
573 tp->GetImageSkiaNamed(normal_image_id)); | 525 tp->GetImageSkiaNamed(normal_image_id)); |
574 button->SetImage(views::CustomButton::STATE_HOVERED, | 526 button->SetImage(views::CustomButton::STATE_HOVERED, |
575 tp->GetImageSkiaNamed(hot_image_id)); | 527 tp->GetImageSkiaNamed(hot_image_id)); |
576 button->SetImage(views::CustomButton::STATE_PRESSED, | 528 button->SetImage(views::CustomButton::STATE_PRESSED, |
577 tp->GetImageSkiaNamed(pushed_image_id)); | 529 tp->GetImageSkiaNamed(pushed_image_id)); |
578 if (browser_view()->IsBrowserTypeNormal()) { | 530 if (browser_view()->IsBrowserTypeNormal()) { |
579 button->SetBackground( | 531 button->SetBackground( |
580 tp->GetColor(ThemeProperties::COLOR_BUTTON_BACKGROUND), | 532 tp->GetColor(ThemeProperties::COLOR_BUTTON_BACKGROUND), |
581 tp->GetImageSkiaNamed(IDR_THEME_WINDOW_CONTROL_BACKGROUND), | 533 tp->GetImageSkiaNamed(IDR_THEME_WINDOW_CONTROL_BACKGROUND), |
582 tp->GetImageSkiaNamed(mask_image_id)); | 534 tp->GetImageSkiaNamed(mask_image_id)); |
583 } | 535 } |
584 button->SetAccessibleName( | 536 button->SetAccessibleName( |
585 l10n_util::GetStringUTF16(accessibility_string_id)); | 537 l10n_util::GetStringUTF16(accessibility_string_id)); |
538 button->set_id(view_id); | |
586 AddChildView(button); | 539 AddChildView(button); |
587 return button; | 540 return button; |
588 } | 541 } |
589 | 542 |
590 int OpaqueBrowserFrameView::FrameBorderThickness(bool restored) const { | 543 int OpaqueBrowserFrameView::FrameBorderThickness(bool restored) const { |
591 return (!restored && (frame()->IsMaximized() || frame()->IsFullscreen())) ? | 544 return layout_->FrameBorderThickness(restored); |
592 0 : kFrameBorderThickness; | |
593 } | 545 } |
594 | 546 |
595 int OpaqueBrowserFrameView::TopResizeHeight() const { | 547 int OpaqueBrowserFrameView::TopResizeHeight() const { |
596 return FrameBorderThickness(false) - kTopResizeAdjust; | 548 return FrameBorderThickness(false) - kTopResizeAdjust; |
597 } | 549 } |
598 | 550 |
599 int OpaqueBrowserFrameView::NonClientBorderThickness() const { | 551 int OpaqueBrowserFrameView::NonClientBorderThickness() const { |
600 // When we fill the screen, we don't show a client edge. | 552 return layout_->NonClientBorderThickness(); |
601 return FrameBorderThickness(false) + | |
602 ((frame()->IsMaximized() || frame()->IsFullscreen()) ? | |
603 0 : kClientEdgeThickness); | |
604 } | |
605 | |
606 int OpaqueBrowserFrameView::CaptionButtonY(bool restored) const { | |
607 // Maximized buttons start at window top so that even if their images aren't | |
608 // drawn flush with the screen edge, they still obey Fitts' Law. | |
609 return (!restored && frame()->IsMaximized()) ? | |
610 FrameBorderThickness(false) : kFrameShadowThickness; | |
611 } | |
612 | |
613 int OpaqueBrowserFrameView::TitlebarBottomThickness(bool restored) const { | |
614 return kTitlebarTopAndBottomEdgeThickness + | |
615 ((!restored && frame()->IsMaximized()) ? 0 : kClientEdgeThickness); | |
616 } | |
617 | |
618 int OpaqueBrowserFrameView::IconSize() const { | |
619 #if defined(OS_WIN) | |
620 // This metric scales up if either the titlebar height or the titlebar font | |
621 // size are increased. | |
622 return GetSystemMetrics(SM_CYSMICON); | |
623 #else | |
624 return std::max(BrowserFrame::GetTitleFont().GetHeight(), kIconMinimumSize); | |
625 #endif | |
626 } | 553 } |
627 | 554 |
628 gfx::Rect OpaqueBrowserFrameView::IconBounds() const { | 555 gfx::Rect OpaqueBrowserFrameView::IconBounds() const { |
629 int size = IconSize(); | 556 return layout_->IconBounds(); |
630 int frame_thickness = FrameBorderThickness(false); | |
631 int y; | |
632 views::WidgetDelegate* delegate = frame()->widget_delegate(); | |
633 if (delegate && (delegate->ShouldShowWindowIcon() || | |
634 delegate->ShouldShowWindowTitle())) { | |
635 // Our frame border has a different "3D look" than Windows'. Theirs has a | |
636 // more complex gradient on the top that they push their icon/title below; | |
637 // then the maximized window cuts this off and the icon/title are centered | |
638 // in the remaining space. Because the apparent shape of our border is | |
639 // simpler, using the same positioning makes things look slightly uncentered | |
640 // with restored windows, so when the window is restored, instead of | |
641 // calculating the remaining space from below the frame border, we calculate | |
642 // from below the 3D edge. | |
643 int unavailable_px_at_top = frame()->IsMaximized() ? | |
644 frame_thickness : kTitlebarTopAndBottomEdgeThickness; | |
645 // When the icon is shorter than the minimum space we reserve for the | |
646 // caption button, we vertically center it. We want to bias rounding to put | |
647 // extra space above the icon, since the 3D edge (+ client edge, for | |
648 // restored windows) below looks (to the eye) more like additional space | |
649 // than does the 3D edge (or nothing at all, for maximized windows) above; | |
650 // hence the +1. | |
651 y = unavailable_px_at_top + (NonClientTopBorderHeight(false) - | |
652 unavailable_px_at_top - size - TitlebarBottomThickness(false) + 1) / 2; | |
653 } else { | |
654 // For "browser mode" windows, we use the native positioning, which is just | |
655 // below the top frame border. | |
656 y = frame_thickness; | |
657 } | |
658 return gfx::Rect(frame_thickness + kIconLeftSpacing, y, size, size); | |
659 } | |
660 | |
661 gfx::Rect OpaqueBrowserFrameView::GetBoundsForTabStripAndAvatarArea( | |
662 views::View* tabstrip) const { | |
663 int available_width = width(); | |
664 if (minimize_button_) { | |
665 available_width = minimize_button_->x(); | |
666 } else if (browser_view()->window_switcher_button()) { | |
667 // We don't have the sysmenu buttons in Windows 8 metro mode. However there | |
668 // are buttons like the window switcher which are drawn in the non client | |
669 // are in the BrowserView. We need to ensure that the tab strip does not | |
670 // draw on the window switcher button. | |
671 available_width -= browser_view()->window_switcher_button()->width(); | |
672 } | |
673 const int caption_spacing = frame()->IsMaximized() ? | |
674 kNewTabCaptionMaximizedSpacing : kNewTabCaptionRestoredSpacing; | |
675 const int tabstrip_x = NonClientBorderThickness(); | |
676 const int tabstrip_width = available_width - tabstrip_x - caption_spacing; | |
677 return gfx::Rect(tabstrip_x, GetTabStripInsets(false).top, | |
678 std::max(0, tabstrip_width), | |
679 tabstrip->GetPreferredSize().height()); | |
680 } | 557 } |
681 | 558 |
682 void OpaqueBrowserFrameView::PaintRestoredFrameBorder(gfx::Canvas* canvas) { | 559 void OpaqueBrowserFrameView::PaintRestoredFrameBorder(gfx::Canvas* canvas) { |
683 frame_background_->set_frame_color(GetFrameColor()); | 560 frame_background_->set_frame_color(GetFrameColor()); |
684 frame_background_->set_theme_image(GetFrameImage()); | 561 frame_background_->set_theme_image(GetFrameImage()); |
685 frame_background_->set_theme_overlay_image(GetFrameOverlayImage()); | 562 frame_background_->set_theme_overlay_image(GetFrameOverlayImage()); |
686 frame_background_->set_top_area_height(GetTopAreaHeight()); | 563 frame_background_->set_top_area_height(GetTopAreaHeight()); |
687 | 564 |
688 ui::ThemeProvider* tp = GetThemeProvider(); | 565 ui::ThemeProvider* tp = GetThemeProvider(); |
689 frame_background_->SetSideImages( | 566 frame_background_->SetSideImages( |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
838 kClientEdgeThickness), | 715 kClientEdgeThickness), |
839 ThemeProperties::GetDefaultColor( | 716 ThemeProperties::GetDefaultColor( |
840 ThemeProperties::COLOR_TOOLBAR_SEPARATOR)); | 717 ThemeProperties::COLOR_TOOLBAR_SEPARATOR)); |
841 } | 718 } |
842 | 719 |
843 void OpaqueBrowserFrameView::PaintRestoredClientEdge(gfx::Canvas* canvas) { | 720 void OpaqueBrowserFrameView::PaintRestoredClientEdge(gfx::Canvas* canvas) { |
844 ui::ThemeProvider* tp = GetThemeProvider(); | 721 ui::ThemeProvider* tp = GetThemeProvider(); |
845 int client_area_top = frame()->client_view()->y(); | 722 int client_area_top = frame()->client_view()->y(); |
846 int image_top = client_area_top; | 723 int image_top = client_area_top; |
847 | 724 |
848 gfx::Rect client_area_bounds = CalculateClientAreaBounds(width(), height()); | 725 gfx::Rect client_area_bounds = |
726 layout_->CalculateClientAreaBounds(width(), height()); | |
849 SkColor toolbar_color = tp->GetColor(ThemeProperties::COLOR_TOOLBAR); | 727 SkColor toolbar_color = tp->GetColor(ThemeProperties::COLOR_TOOLBAR); |
850 | 728 |
851 if (browser_view()->IsToolbarVisible()) { | 729 if (browser_view()->IsToolbarVisible()) { |
852 // The client edge images always start below the toolbar corner images. The | 730 // The client edge images always start below the toolbar corner images. The |
853 // client edge filled rects start there or at the bottom of the toolbar, | 731 // client edge filled rects start there or at the bottom of the toolbar, |
854 // whichever is shorter. | 732 // whichever is shorter. |
855 gfx::Rect toolbar_bounds(browser_view()->GetToolbarBounds()); | 733 gfx::Rect toolbar_bounds(browser_view()->GetToolbarBounds()); |
856 image_top += toolbar_bounds.y() + | 734 image_top += toolbar_bounds.y() + |
857 tp->GetImageSkiaNamed(IDR_CONTENT_TOP_LEFT_CORNER)->height(); | 735 tp->GetImageSkiaNamed(IDR_CONTENT_TOP_LEFT_CORNER)->height(); |
858 client_area_top = std::min(image_top, | 736 client_area_top = std::min(image_top, |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
982 | 860 |
983 int OpaqueBrowserFrameView::GetTopAreaHeight() const { | 861 int OpaqueBrowserFrameView::GetTopAreaHeight() const { |
984 gfx::ImageSkia* frame_image = GetFrameImage(); | 862 gfx::ImageSkia* frame_image = GetFrameImage(); |
985 int top_area_height = frame_image->height(); | 863 int top_area_height = frame_image->height(); |
986 if (browser_view()->IsTabStripVisible()) { | 864 if (browser_view()->IsTabStripVisible()) { |
987 top_area_height = std::max(top_area_height, | 865 top_area_height = std::max(top_area_height, |
988 GetBoundsForTabStrip(browser_view()->tabstrip()).bottom()); | 866 GetBoundsForTabStrip(browser_view()->tabstrip()).bottom()); |
989 } | 867 } |
990 return top_area_height; | 868 return top_area_height; |
991 } | 869 } |
992 | |
993 void OpaqueBrowserFrameView::LayoutWindowControls() { | |
994 if (!ShouldAddDefaultCaptionButtons()) | |
995 return; | |
996 bool is_maximized = frame()->IsMaximized(); | |
997 close_button_->SetImageAlignment(views::ImageButton::ALIGN_LEFT, | |
998 views::ImageButton::ALIGN_BOTTOM); | |
999 int caption_y = CaptionButtonY(false); | |
1000 // There should always be the same number of non-shadow pixels visible to the | |
1001 // side of the caption buttons. In maximized mode we extend the rightmost | |
1002 // button to the screen corner to obey Fitts' Law. | |
1003 int right_extra_width = is_maximized ? | |
1004 (kFrameBorderThickness - kFrameShadowThickness) : 0; | |
1005 gfx::Size close_button_size = close_button_->GetPreferredSize(); | |
1006 close_button_->SetBounds(width() - FrameBorderThickness(false) - | |
1007 right_extra_width - close_button_size.width(), caption_y, | |
1008 close_button_size.width() + right_extra_width, | |
1009 close_button_size.height()); | |
1010 | |
1011 // When the window is restored, we show a maximized button; otherwise, we show | |
1012 // a restore button. | |
1013 bool is_restored = !is_maximized && !frame()->IsMinimized(); | |
1014 views::ImageButton* invisible_button = is_restored ? | |
1015 restore_button_ : maximize_button_; | |
1016 invisible_button->SetVisible(false); | |
1017 | |
1018 views::ImageButton* visible_button = is_restored ? | |
1019 maximize_button_ : restore_button_; | |
1020 visible_button->SetVisible(true); | |
1021 visible_button->SetImageAlignment(views::ImageButton::ALIGN_LEFT, | |
1022 views::ImageButton::ALIGN_BOTTOM); | |
1023 gfx::Size visible_button_size = visible_button->GetPreferredSize(); | |
1024 visible_button->SetBounds(close_button_->x() - visible_button_size.width(), | |
1025 caption_y, visible_button_size.width(), | |
1026 visible_button_size.height()); | |
1027 | |
1028 minimize_button_->SetVisible(true); | |
1029 minimize_button_->SetImageAlignment(views::ImageButton::ALIGN_LEFT, | |
1030 views::ImageButton::ALIGN_BOTTOM); | |
1031 gfx::Size minimize_button_size = minimize_button_->GetPreferredSize(); | |
1032 minimize_button_->SetBounds( | |
1033 visible_button->x() - minimize_button_size.width(), caption_y, | |
1034 minimize_button_size.width(), | |
1035 minimize_button_size.height()); | |
1036 } | |
1037 | |
1038 void OpaqueBrowserFrameView::LayoutTitleBar() { | |
1039 const views::WidgetDelegate* delegate = frame()->widget_delegate(); | |
1040 if (delegate) { | |
1041 gfx::Rect icon_bounds(IconBounds()); | |
1042 if (delegate->ShouldShowWindowIcon()) | |
1043 window_icon_->SetBoundsRect(icon_bounds); | |
1044 | |
1045 window_title_->SetVisible(delegate->ShouldShowWindowTitle()); | |
1046 if (delegate->ShouldShowWindowTitle()) { | |
1047 window_title_->SetText(delegate->GetWindowTitle()); | |
1048 const int title_x = delegate->ShouldShowWindowIcon() ? | |
1049 icon_bounds.right() + kIconTitleSpacing : icon_bounds.x(); | |
1050 window_title_->SetBounds(title_x, icon_bounds.y(), | |
1051 std::max(0, minimize_button_->x() - kTitleLogoSpacing - title_x), | |
1052 icon_bounds.height()); | |
1053 } | |
1054 } | |
1055 } | |
1056 | |
1057 void OpaqueBrowserFrameView::LayoutAvatar() { | |
1058 // Even though the avatar is used for both incognito and profiles we always | |
1059 // use the incognito icon to layout the avatar button. The profile icon | |
1060 // can be customized so we can't depend on its size to perform layout. | |
1061 gfx::ImageSkia incognito_icon = browser_view()->GetOTRAvatarIcon(); | |
1062 | |
1063 int avatar_bottom = GetTabStripInsets(false).top + | |
1064 browser_view()->GetTabStripHeight() - kAvatarBottomSpacing; | |
1065 int avatar_restored_y = avatar_bottom - incognito_icon.height(); | |
1066 int avatar_y = frame()->IsMaximized() ? | |
1067 (NonClientTopBorderHeight(false) + kTabstripTopShadowThickness) : | |
1068 avatar_restored_y; | |
1069 avatar_bounds_.SetRect(NonClientBorderThickness() + kAvatarLeftSpacing, | |
1070 avatar_y, incognito_icon.width(), | |
1071 browser_view()->ShouldShowAvatar() ? (avatar_bottom - avatar_y) : 0); | |
1072 if (avatar_button()) | |
1073 avatar_button()->SetBoundsRect(avatar_bounds_); | |
1074 | |
1075 if (avatar_label()) { | |
1076 // Space between the bottom of the avatar and the bottom of the avatar | |
1077 // label. | |
1078 const int kAvatarLabelBottomSpacing = 3; | |
1079 // Space between the frame border and the left edge of the avatar label. | |
1080 const int kAvatarLabelLeftSpacing = -1; | |
1081 gfx::Size label_size = avatar_label()->GetPreferredSize(); | |
1082 gfx::Rect label_bounds( | |
1083 FrameBorderThickness(false) + kAvatarLabelLeftSpacing, | |
1084 avatar_bottom - kAvatarLabelBottomSpacing - label_size.height(), | |
1085 label_size.width(), | |
1086 browser_view()->ShouldShowAvatar() ? label_size.height() : 0); | |
1087 avatar_label()->SetBoundsRect(label_bounds); | |
1088 } | |
1089 } | |
1090 | |
1091 gfx::Rect OpaqueBrowserFrameView::CalculateClientAreaBounds(int width, | |
1092 int height) const { | |
1093 int top_height = NonClientTopBorderHeight(false); | |
1094 int border_thickness = NonClientBorderThickness(); | |
1095 return gfx::Rect(border_thickness, top_height, | |
1096 std::max(0, width - (2 * border_thickness)), | |
1097 std::max(0, height - GetReservedHeight() - | |
1098 top_height - border_thickness)); | |
1099 } | |
OLD | NEW |