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.
5 #include "chrome/browser/ui/views/frame/opaque_browser_frame_view_layout.h"
7 #include "chrome/browser/profiles/profiles_state.h"
8 #include "chrome/browser/ui/views/avatar_label.h"
9 #include "chrome/browser/ui/views/avatar_menu_button.h"
10 #include "chrome/common/profile_management_switches.h"
11 #include "ui/gfx/font.h"
12 #include "ui/views/controls/button/image_button.h"
13 #include "ui/views/controls/label.h"
16 #include "win8/util/win8_util.h"
21 // Besides the frame border, there's another 9 px of empty space atop the
22 // window in restored mode, to use to drag the window around.
23 const int kNonClientRestoredExtraThickness
= 9;
25 // The titlebar never shrinks too short to show the caption button plus some
27 const int kCaptionButtonHeightWithPadding
= 19;
29 // There is a 5 px gap between the title text and the caption buttons.
30 const int kTitleLogoSpacing
= 5;
32 // The frame border is only visible in restored mode and is hardcoded to 4 px on
33 // each side regardless of the system window border size.
34 const int kFrameBorderThickness
= 4;
36 // The titlebar has a 2 px 3D edge along the top and bottom.
37 const int kTitlebarTopAndBottomEdgeThickness
= 2;
39 // The icon is inset 2 px from the left frame border.
40 const int kIconLeftSpacing
= 2;
42 // There is a 4 px gap between the icon and the title text.
43 const int kIconTitleSpacing
= 4;
45 // The avatar ends 2 px above the bottom of the tabstrip (which, given the
46 // way the tabstrip draws its bottom edge, will appear like a 1 px gap to the
48 const int kAvatarBottomSpacing
= 2;
50 // Space between the frame border and the edge of the avatar.
51 const int kAvatarOuterSpacing
= 2;
53 // Space between the edge of the avatar and the tabstrip.
54 const int kAvatarInnerSpacing
= 4;
56 // Space between the trailing edge of the avatar label and the tabstrip.
57 const int kAvatarLabelInnerSpacing
= 10;
59 // How far the new avatar button is from the closest caption button.
60 const int kNewAvatarButtonOffset
= 5;
62 // In restored mode, the New Tab button isn't at the same height as the caption
63 // buttons, but the space will look cluttered if it actually slides under them,
64 // so we stop it when the gap between the two is down to 5 px.
65 const int kNewTabCaptionRestoredSpacing
= 5;
67 // In maximized mode, where the New Tab button and the caption buttons are at
68 // similar vertical coordinates, we need to reserve a larger, 16 px gap to avoid
69 // looking too cluttered.
70 const int kNewTabCaptionMaximizedSpacing
= 16;
72 // If there are no caption buttons to the right of the New Tab button, we
73 // reserve a small 5px gap, regardless of whether the window is maximized. This
74 // overrides the two previous constants.
75 const int kNewTabNoCaptionButtonsSpacing
= 5;
77 // The top 3 px of the tabstrip is shadow; in maximized mode we push this off
78 // the top of the screen so the tabs appear flush against the screen edge.
79 const int kTabstripTopShadowThickness
= 3;
81 // How far to indent the tabstrip from the left side of the screen when there
83 const int kTabStripIndent
= -6;
85 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
86 // Default extra space between the top of the frame and the top of the window
88 const int kExtraCaption
= 2;
90 // Default extra spacing between individual window caption buttons.
91 const int kCaptionButtonSpacing
= 2;
93 const int kExtraCaption
= 0;
94 const int kCaptionButtonSpacing
= 0;
99 ///////////////////////////////////////////////////////////////////////////////
100 // OpaqueBrowserFrameView, public:
102 OpaqueBrowserFrameViewLayout::OpaqueBrowserFrameViewLayout(
103 OpaqueBrowserFrameViewLayoutDelegate
* delegate
)
104 : delegate_(delegate
),
105 leading_button_start_(0),
106 trailing_button_start_(0),
107 minimum_size_for_buttons_(0),
108 has_leading_buttons_(false),
109 has_trailing_buttons_(false),
110 extra_caption_y_(kExtraCaption
),
111 window_caption_spacing_(kCaptionButtonSpacing
),
112 minimize_button_(NULL
),
113 maximize_button_(NULL
),
114 restore_button_(NULL
),
119 avatar_button_(NULL
),
120 new_avatar_button_(NULL
) {
121 trailing_buttons_
.push_back(views::FRAME_BUTTON_MINIMIZE
);
122 trailing_buttons_
.push_back(views::FRAME_BUTTON_MAXIMIZE
);
123 trailing_buttons_
.push_back(views::FRAME_BUTTON_CLOSE
);
126 OpaqueBrowserFrameViewLayout::~OpaqueBrowserFrameViewLayout() {}
129 bool OpaqueBrowserFrameViewLayout::ShouldAddDefaultCaptionButtons() {
131 return !win8::IsSingleWindowMetroMode();
136 void OpaqueBrowserFrameViewLayout::SetButtonOrdering(
137 const std::vector
<views::FrameButton
>& leading_buttons
,
138 const std::vector
<views::FrameButton
>& trailing_buttons
) {
139 leading_buttons_
= leading_buttons
;
140 trailing_buttons_
= trailing_buttons
;
143 gfx::Rect
OpaqueBrowserFrameViewLayout::GetBoundsForTabStrip(
144 const gfx::Size
& tabstrip_preferred_size
,
145 int available_width
) const {
146 available_width
-= trailing_button_start_
;
147 available_width
-= leading_button_start_
;
149 if (delegate_
->GetAdditionalReservedSpaceInTabStrip())
150 available_width
-= delegate_
->GetAdditionalReservedSpaceInTabStrip();
152 const int caption_spacing
= NewTabCaptionSpacing();
153 const int tabstrip_width
= available_width
- caption_spacing
;
154 gfx::Rect
bounds(leading_button_start_
, GetTabStripInsetsTop(false),
155 std::max(0, tabstrip_width
),
156 tabstrip_preferred_size
.height());
158 int leading_tabstrip_indent
= kTabStripIndent
;
159 if (delegate_
->ShouldShowAvatar() && !ShouldAvatarBeOnRight()) {
160 if (avatar_label_
&& avatar_label_
->bounds().width())
161 leading_tabstrip_indent
+= kAvatarLabelInnerSpacing
;
163 leading_tabstrip_indent
+= kAvatarInnerSpacing
;
165 bounds
.Inset(leading_tabstrip_indent
, 0, 0, 0);
169 gfx::Size
OpaqueBrowserFrameViewLayout::GetMinimumSize(
170 int available_width
) const {
171 gfx::Size min_size
= delegate_
->GetBrowserViewMinimumSize();
172 int border_thickness
= NonClientBorderThickness();
173 min_size
.Enlarge(2 * border_thickness
,
174 NonClientTopBorderHeight(false) + border_thickness
);
176 // Ensure that we can, at minimum, hold our window controls and avatar icon.
177 min_size
.set_width(std::max(min_size
.width(), minimum_size_for_buttons_
));
179 // Ensure that the minimum width is enough to hold a minimum width tab strip
180 // at its usual insets.
181 if (delegate_
->IsTabStripVisible()) {
182 gfx::Size preferred_size
= delegate_
->GetTabstripPreferredSize();
183 const int min_tabstrip_width
= preferred_size
.width();
184 const int caption_spacing
= NewTabCaptionSpacing();
185 min_size
.Enlarge(min_tabstrip_width
+ caption_spacing
, 0);
191 gfx::Rect
OpaqueBrowserFrameViewLayout::GetWindowBoundsForClientBounds(
192 const gfx::Rect
& client_bounds
) const {
193 int top_height
= NonClientTopBorderHeight(false);
194 int border_thickness
= NonClientBorderThickness();
195 return gfx::Rect(std::max(0, client_bounds
.x() - border_thickness
),
196 std::max(0, client_bounds
.y() - top_height
),
197 client_bounds
.width() + (2 * border_thickness
),
198 client_bounds
.height() + top_height
+ border_thickness
);
201 int OpaqueBrowserFrameViewLayout::FrameBorderThickness(bool restored
) const {
202 return (!restored
&& (delegate_
->IsMaximized() ||
203 delegate_
->IsFullscreen())) ?
204 0 : kFrameBorderThickness
;
207 int OpaqueBrowserFrameViewLayout::NonClientBorderThickness() const {
208 // When we fill the screen, we don't show a client edge.
209 return FrameBorderThickness(false) +
210 ((delegate_
->IsMaximized() || delegate_
->IsFullscreen()) ?
211 0 : views::NonClientFrameView::kClientEdgeThickness
);
214 int OpaqueBrowserFrameViewLayout::NonClientTopBorderHeight(
215 bool restored
) const {
216 if (delegate_
->ShouldShowWindowTitle()) {
217 return std::max(FrameBorderThickness(restored
) + delegate_
->GetIconSize(),
218 CaptionButtonY(restored
) + kCaptionButtonHeightWithPadding
) +
219 TitlebarBottomThickness(restored
);
222 return FrameBorderThickness(restored
) -
223 ((delegate_
->IsTabStripVisible() &&
224 !restored
&& !delegate_
->ShouldLeaveOffsetNearTopBorder())
225 ? kTabstripTopShadowThickness
: 0);
228 int OpaqueBrowserFrameViewLayout::GetTabStripInsetsTop(bool restored
) const {
229 return NonClientTopBorderHeight(restored
) + ((!restored
&&
230 (!delegate_
->ShouldLeaveOffsetNearTopBorder() ||
231 delegate_
->IsFullscreen())) ?
232 0 : kNonClientRestoredExtraThickness
);
235 int OpaqueBrowserFrameViewLayout::TitlebarBottomThickness(bool restored
) const {
236 return kTitlebarTopAndBottomEdgeThickness
+
237 ((!restored
&& delegate_
->IsMaximized()) ? 0 :
238 views::NonClientFrameView::kClientEdgeThickness
);
241 int OpaqueBrowserFrameViewLayout::CaptionButtonY(bool restored
) const {
242 // Maximized buttons start at window top, since the window has no border. This
243 // offset is for the image (the actual clickable bounds extend all the way to
244 // the top to take Fitts' Law into account).
245 return ((!restored
&& delegate_
->IsMaximized()) ?
246 FrameBorderThickness(false) :
247 views::NonClientFrameView::kFrameShadowThickness
) + extra_caption_y_
;
250 gfx::Rect
OpaqueBrowserFrameViewLayout::IconBounds() const {
251 return window_icon_bounds_
;
254 gfx::Rect
OpaqueBrowserFrameViewLayout::CalculateClientAreaBounds(
257 int top_height
= NonClientTopBorderHeight(false);
258 int border_thickness
= NonClientBorderThickness();
259 return gfx::Rect(border_thickness
, top_height
,
260 std::max(0, width
- (2 * border_thickness
)),
261 std::max(0, height
- top_height
- border_thickness
));
264 ///////////////////////////////////////////////////////////////////////////////
265 // OpaqueBrowserFrameView, private:
267 bool OpaqueBrowserFrameViewLayout::ShouldAvatarBeOnRight() const {
268 // The avatar should be shown either on the end of the left or the beginning
269 // of the right depending on which side has fewer buttons.
270 return trailing_buttons_
.size() < leading_buttons_
.size();
273 int OpaqueBrowserFrameViewLayout::NewTabCaptionSpacing() const {
274 return has_trailing_buttons_
275 ? (delegate_
->IsMaximized() ? kNewTabCaptionMaximizedSpacing
276 : kNewTabCaptionRestoredSpacing
)
277 : kNewTabNoCaptionButtonsSpacing
;
280 void OpaqueBrowserFrameViewLayout::LayoutWindowControls(views::View
* host
) {
281 if (!ShouldAddDefaultCaptionButtons())
284 int caption_y
= CaptionButtonY(false);
286 // Keep a list of all buttons that we don't show.
287 std::vector
<views::FrameButton
> buttons_not_shown
;
288 buttons_not_shown
.push_back(views::FRAME_BUTTON_MAXIMIZE
);
289 buttons_not_shown
.push_back(views::FRAME_BUTTON_MINIMIZE
);
290 buttons_not_shown
.push_back(views::FRAME_BUTTON_CLOSE
);
292 if (delegate_
->ShouldShowCaptionButtons()) {
293 for (std::vector
<views::FrameButton
>::const_iterator it
=
294 leading_buttons_
.begin(); it
!= leading_buttons_
.end(); ++it
) {
295 ConfigureButton(host
, *it
, ALIGN_LEADING
, caption_y
);
296 buttons_not_shown
.erase(
297 std::remove(buttons_not_shown
.begin(), buttons_not_shown
.end(), *it
),
298 buttons_not_shown
.end());
301 for (std::vector
<views::FrameButton
>::const_reverse_iterator it
=
302 trailing_buttons_
.rbegin(); it
!= trailing_buttons_
.rend(); ++it
) {
303 ConfigureButton(host
, *it
, ALIGN_TRAILING
, caption_y
);
304 buttons_not_shown
.erase(
305 std::remove(buttons_not_shown
.begin(), buttons_not_shown
.end(), *it
),
306 buttons_not_shown
.end());
310 for (std::vector
<views::FrameButton
>::const_iterator it
=
311 buttons_not_shown
.begin(); it
!= buttons_not_shown
.end(); ++it
) {
316 void OpaqueBrowserFrameViewLayout::LayoutTitleBar(views::View
* host
) {
317 bool use_hidden_icon_location
= true;
319 int size
= delegate_
->GetIconSize();
320 int frame_thickness
= FrameBorderThickness(false);
321 bool should_show_icon
= delegate_
->ShouldShowWindowIcon();
322 bool should_show_title
= delegate_
->ShouldShowWindowTitle();
324 if (should_show_icon
|| should_show_title
) {
325 use_hidden_icon_location
= false;
327 // Our frame border has a different "3D look" than Windows'. Theirs has
328 // a more complex gradient on the top that they push their icon/title
329 // below; then the maximized window cuts this off and the icon/title are
330 // centered in the remaining space. Because the apparent shape of our
331 // border is simpler, using the same positioning makes things look
332 // slightly uncentered with restored windows, so when the window is
333 // restored, instead of calculating the remaining space from below the
334 // frame border, we calculate from below the 3D edge.
335 int unavailable_px_at_top
= delegate_
->IsMaximized() ?
336 frame_thickness
: kTitlebarTopAndBottomEdgeThickness
;
337 // When the icon is shorter than the minimum space we reserve for the
338 // caption button, we vertically center it. We want to bias rounding to
339 // put extra space above the icon, since the 3D edge (+ client edge, for
340 // restored windows) below looks (to the eye) more like additional space
341 // than does the 3D edge (or nothing at all, for maximized windows)
342 // above; hence the +1.
343 int y
= unavailable_px_at_top
+ (NonClientTopBorderHeight(false) -
344 unavailable_px_at_top
- size
-
345 TitlebarBottomThickness(false) + 1) / 2;
347 window_icon_bounds_
= gfx::Rect(leading_button_start_
+ kIconLeftSpacing
, y
,
349 leading_button_start_
+= size
+ kIconLeftSpacing
;
350 minimum_size_for_buttons_
+= size
+ kIconLeftSpacing
;
353 if (should_show_icon
)
354 window_icon_
->SetBoundsRect(window_icon_bounds_
);
357 window_title_
->SetVisible(should_show_title
);
358 if (should_show_title
) {
359 window_title_
->SetText(delegate_
->GetWindowTitle());
361 int text_width
= std::max(
362 0, host
->width() - trailing_button_start_
- kTitleLogoSpacing
-
363 leading_button_start_
- kIconTitleSpacing
);
364 window_title_
->SetBounds(leading_button_start_
+ kIconTitleSpacing
,
365 window_icon_bounds_
.y(),
366 text_width
, window_icon_bounds_
.height());
367 leading_button_start_
+= text_width
+ kIconTitleSpacing
;
371 if (use_hidden_icon_location
) {
372 if (has_leading_buttons_
) {
373 // There are window button icons on the left. Don't size the hidden window
374 // icon that people can double click on to close the window.
375 window_icon_bounds_
= gfx::Rect();
377 // We set the icon bounds to a small rectangle in the top leading corner
378 // if there are no icons on the leading side.
379 window_icon_bounds_
= gfx::Rect(
380 frame_thickness
+ kIconLeftSpacing
, frame_thickness
, size
, size
);
385 void OpaqueBrowserFrameViewLayout::LayoutNewStyleAvatar(views::View
* host
) {
386 DCHECK(switches::IsNewProfileManagement());
387 if (!new_avatar_button_
)
390 gfx::Size label_size
= new_avatar_button_
->GetPreferredSize();
391 int button_size_with_offset
= kNewAvatarButtonOffset
+ label_size
.width();
393 int button_x
= host
->width() - trailing_button_start_
-
394 button_size_with_offset
;
395 int button_y
= CaptionButtonY(false);
397 trailing_button_start_
+= button_size_with_offset
;
398 minimum_size_for_buttons_
+= button_size_with_offset
;
400 new_avatar_button_
->SetBounds(
404 button_y
+ kCaptionButtonHeightWithPadding
);
407 void OpaqueBrowserFrameViewLayout::LayoutAvatar(views::View
* host
) {
408 // Even though the avatar is used for both incognito and profiles we always
409 // use the incognito icon to layout the avatar button. The profile icon
410 // can be customized so we can't depend on its size to perform layout.
411 gfx::ImageSkia incognito_icon
= delegate_
->GetOTRAvatarIcon();
413 bool avatar_on_right
= ShouldAvatarBeOnRight();
414 int avatar_bottom
= GetTabStripInsetsTop(false) +
415 delegate_
->GetTabStripHeight() - kAvatarBottomSpacing
;
416 int avatar_restored_y
= avatar_bottom
- incognito_icon
.height();
417 int avatar_x
= avatar_on_right
?
418 host
->width() - trailing_button_start_
- kAvatarOuterSpacing
-
419 incognito_icon
.width() :
420 leading_button_start_
+ kAvatarOuterSpacing
;
421 int avatar_y
= delegate_
->IsMaximized() ?
422 (NonClientTopBorderHeight(false) + kTabstripTopShadowThickness
) :
424 avatar_bounds_
.SetRect(
427 incognito_icon
.width(),
428 delegate_
->ShouldShowAvatar() ? (avatar_bottom
- avatar_y
) : 0);
429 if (avatar_button_
) {
430 avatar_button_
->set_button_on_right(avatar_on_right
);
431 avatar_button_
->SetBoundsRect(avatar_bounds_
);
435 avatar_label_
->SetLabelOnRight(avatar_on_right
);
436 // Space between the bottom of the avatar and the bottom of the avatar
438 const int kAvatarLabelBottomSpacing
= 3;
439 gfx::Size label_size
= avatar_label_
->GetPreferredSize();
440 // The outside edge of the avatar label should be just outside that of the
441 // avatar menu button.
442 int avatar_label_x
= avatar_on_right
?
443 (host
->width() - trailing_button_start_
- label_size
.width()) :
444 leading_button_start_
;
445 gfx::Rect
label_bounds(
447 avatar_bottom
- kAvatarLabelBottomSpacing
- label_size
.height(),
449 delegate_
->ShouldShowAvatar() ? label_size
.height() : 0);
450 avatar_label_
->SetBoundsRect(label_bounds
);
451 edge_offset
= label_size
.width();
453 edge_offset
= kAvatarOuterSpacing
+ incognito_icon
.width();
456 trailing_button_start_
+= edge_offset
;
458 leading_button_start_
+= edge_offset
;
460 // We just add the avatar button size to the minimum size because clicking
461 // the avatar label does the same thing as clicking the avatar button.
462 minimum_size_for_buttons_
+= kAvatarOuterSpacing
+ incognito_icon
.width();
466 void OpaqueBrowserFrameViewLayout::ConfigureButton(
468 views::FrameButton button_id
,
469 ButtonAlignment alignment
,
472 case views::FRAME_BUTTON_MINIMIZE
: {
473 minimize_button_
->SetVisible(true);
474 SetBoundsForButton(host
, minimize_button_
, alignment
, caption_y
);
477 case views::FRAME_BUTTON_MAXIMIZE
: {
478 // When the window is restored, we show a maximized button; otherwise, we
479 // show a restore button.
480 bool is_restored
= !delegate_
->IsMaximized() && !delegate_
->IsMinimized();
481 views::ImageButton
* invisible_button
= is_restored
?
482 restore_button_
: maximize_button_
;
483 invisible_button
->SetVisible(false);
485 views::ImageButton
* visible_button
= is_restored
?
486 maximize_button_
: restore_button_
;
487 visible_button
->SetVisible(true);
488 SetBoundsForButton(host
, visible_button
, alignment
, caption_y
);
491 case views::FRAME_BUTTON_CLOSE
: {
492 close_button_
->SetVisible(true);
493 SetBoundsForButton(host
, close_button_
, alignment
, caption_y
);
499 void OpaqueBrowserFrameViewLayout::HideButton(views::FrameButton button_id
) {
501 case views::FRAME_BUTTON_MINIMIZE
:
502 minimize_button_
->SetVisible(false);
504 case views::FRAME_BUTTON_MAXIMIZE
:
505 restore_button_
->SetVisible(false);
506 maximize_button_
->SetVisible(false);
508 case views::FRAME_BUTTON_CLOSE
:
509 close_button_
->SetVisible(false);
514 void OpaqueBrowserFrameViewLayout::SetBoundsForButton(
516 views::ImageButton
* button
,
517 ButtonAlignment alignment
,
519 gfx::Size button_size
= button
->GetPreferredSize();
521 button
->SetImageAlignment(
522 (alignment
== ALIGN_LEADING
) ?
523 views::ImageButton::ALIGN_RIGHT
: views::ImageButton::ALIGN_LEFT
,
524 views::ImageButton::ALIGN_BOTTOM
);
526 // There should always be the same number of non-shadow pixels visible to the
527 // side of the caption buttons. In maximized mode we extend buttons to the
528 // screen top and the rightmost button to the screen right (or leftmost button
529 // to the screen left, for left-aligned buttons) to obey Fitts' Law.
530 bool is_maximized
= delegate_
->IsMaximized();
532 // When we are the first button on the leading side and are the close
533 // button, we must flip ourselves, because the close button assets have
534 // a little notch to fit in the rounded frame.
535 button
->SetDrawImageMirrored(alignment
== ALIGN_LEADING
&&
536 !has_leading_buttons_
&&
537 button
== close_button_
);
538 // If the window is maximized, align the buttons to its upper edge.
539 int extra_height
= is_maximized
? extra_caption_y_
: 0;
542 case ALIGN_LEADING
: {
543 if (has_leading_buttons_
)
544 leading_button_start_
+= window_caption_spacing_
;
546 // If we're the first button on the left and maximized, add width to the
547 // right hand side of the screen.
548 int extra_width
= (is_maximized
&& !has_leading_buttons_
) ?
549 (kFrameBorderThickness
-
550 views::NonClientFrameView::kFrameShadowThickness
) : 0;
553 leading_button_start_
,
554 caption_y
- extra_height
,
555 button_size
.width() + extra_width
,
556 button_size
.height() + extra_height
);
558 leading_button_start_
+= extra_width
+ button_size
.width();
559 minimum_size_for_buttons_
+= extra_width
+ button_size
.width();
560 has_leading_buttons_
= true;
563 case ALIGN_TRAILING
: {
564 if (has_trailing_buttons_
)
565 trailing_button_start_
+= window_caption_spacing_
;
567 // If we're the first button on the right and maximized, add width to the
568 // right hand side of the screen.
569 int extra_width
= (is_maximized
&& !has_trailing_buttons_
) ?
570 (kFrameBorderThickness
-
571 views::NonClientFrameView::kFrameShadowThickness
) : 0;
574 host
->width() - trailing_button_start_
- extra_width
-
576 caption_y
- extra_height
,
577 button_size
.width() + extra_width
,
578 button_size
.height() + extra_height
);
580 trailing_button_start_
+= extra_width
+ button_size
.width();
581 minimum_size_for_buttons_
+= extra_width
+ button_size
.width();
582 has_trailing_buttons_
= true;
588 void OpaqueBrowserFrameViewLayout::SetView(int id
, views::View
* view
) {
589 // Why do things this way instead of having an Init() method, where we're
590 // passed the views we'll handle? Because OpaqueBrowserFrameView doesn't own
591 // all the views which are part of it. The avatar stuff, for example, will be
592 // added and removed by the base class of OpaqueBrowserFrameView.
594 case VIEW_ID_MINIMIZE_BUTTON
:
596 DCHECK_EQ(std::string(views::ImageButton::kViewClassName
),
597 view
->GetClassName());
599 minimize_button_
= static_cast<views::ImageButton
*>(view
);
601 case VIEW_ID_MAXIMIZE_BUTTON
:
603 DCHECK_EQ(std::string(views::ImageButton::kViewClassName
),
604 view
->GetClassName());
606 maximize_button_
= static_cast<views::ImageButton
*>(view
);
608 case VIEW_ID_RESTORE_BUTTON
:
610 DCHECK_EQ(std::string(views::ImageButton::kViewClassName
),
611 view
->GetClassName());
613 restore_button_
= static_cast<views::ImageButton
*>(view
);
615 case VIEW_ID_CLOSE_BUTTON
:
617 DCHECK_EQ(std::string(views::ImageButton::kViewClassName
),
618 view
->GetClassName());
620 close_button_
= static_cast<views::ImageButton
*>(view
);
622 case VIEW_ID_WINDOW_ICON
:
625 case VIEW_ID_WINDOW_TITLE
:
627 DCHECK_EQ(std::string(views::Label::kViewClassName
),
628 view
->GetClassName());
630 window_title_
= static_cast<views::Label
*>(view
);
632 case VIEW_ID_AVATAR_LABEL
:
633 avatar_label_
= static_cast<AvatarLabel
*>(view
);
635 case VIEW_ID_AVATAR_BUTTON
:
637 DCHECK_EQ(std::string(AvatarMenuButton::kViewClassName
),
638 view
->GetClassName());
640 avatar_button_
= static_cast<AvatarMenuButton
*>(view
);
642 case VIEW_ID_NEW_AVATAR_BUTTON
:
643 new_avatar_button_
= view
;
646 NOTIMPLEMENTED() << "Unknown view id " << id
;
651 ///////////////////////////////////////////////////////////////////////////////
652 // OpaqueBrowserFrameView, views::LayoutManager:
654 void OpaqueBrowserFrameViewLayout::Layout(views::View
* host
) {
655 // Reset all our data so that everything is invisible.
656 int thickness
= FrameBorderThickness(false);
657 leading_button_start_
= thickness
;
658 trailing_button_start_
= thickness
;
659 minimum_size_for_buttons_
= leading_button_start_
+ trailing_button_start_
;
660 has_leading_buttons_
= false;
661 has_trailing_buttons_
= false;
663 LayoutWindowControls(host
);
664 LayoutTitleBar(host
);
666 // We now add a single pixel to the leading spacing. We do this because the
667 // avatar and tab strip start one pixel inward compared to where things start
668 // on the trailing side.
669 leading_button_start_
++;
671 if (delegate_
->IsRegularOrGuestSession() &&
672 switches::IsNewProfileManagement())
673 LayoutNewStyleAvatar(host
);
677 client_view_bounds_
= CalculateClientAreaBounds(
678 host
->width(), host
->height());
681 gfx::Size
OpaqueBrowserFrameViewLayout::GetPreferredSize(views::View
* host
) {
682 // This is never used; NonClientView::GetPreferredSize() will be called
688 void OpaqueBrowserFrameViewLayout::ViewAdded(views::View
* host
,
690 SetView(view
->id(), view
);
693 void OpaqueBrowserFrameViewLayout::ViewRemoved(views::View
* host
,
695 SetView(view
->id(), NULL
);