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 "base/command_line.h"
8 #include "chrome/browser/profiles/profiles_state.h"
9 #include "chrome/browser/ui/views/avatar_label.h"
10 #include "chrome/browser/ui/views/avatar_menu_button.h"
11 #include "chrome/common/chrome_switches.h"
12 #include "chrome/common/profile_management_switches.h"
13 #include "ui/gfx/font.h"
14 #include "ui/views/controls/button/image_button.h"
15 #include "ui/views/controls/label.h"
18 #include "win8/util/win8_util.h"
23 // Besides the frame border, there's another 9 px of empty space atop the
24 // window in restored mode, to use to drag the window around.
25 const int kNonClientRestoredExtraThickness = 9;
27 // The titlebar never shrinks too short to show the caption button plus some
29 const int kCaptionButtonHeightWithPadding = 19;
31 // There is a 5 px gap between the title text and the caption buttons.
32 const int kTitleLogoSpacing = 5;
34 // The frame border is only visible in restored mode and is hardcoded to 4 px on
35 // each side regardless of the system window border size.
36 const int kFrameBorderThickness = 4;
38 // The titlebar has a 2 px 3D edge along the top and bottom.
39 const int kTitlebarTopAndBottomEdgeThickness = 2;
41 // The icon is inset 2 px from the left frame border.
42 const int kIconLeftSpacing = 2;
44 // There is a 4 px gap between the icon and the title text.
45 const int kIconTitleSpacing = 4;
47 // The avatar ends 2 px above the bottom of the tabstrip (which, given the
48 // way the tabstrip draws its bottom edge, will appear like a 1 px gap to the
50 const int kAvatarBottomSpacing = 2;
52 // Space between the frame border and the edge of the avatar.
53 const int kAvatarOuterSpacing = 2;
55 // Space between the edge of the avatar and the tabstrip.
56 const int kAvatarInnerSpacing = 4;
58 // Space between the trailing edge of the avatar label and the tabstrip.
59 const int kAvatarLabelInnerSpacing = 10;
61 // How far the new avatar button is from the closest caption button.
62 const int kNewAvatarButtonOffset = 5;
64 // When the title bar is in its normal two row mode (usually the case for
65 // restored windows), the New Tab button isn't at the same height as the caption
66 // buttons, but the space will look cluttered if it actually slides under them,
67 // so we stop it when the gap between the two is down to 5 px.
68 const int kNewTabCaptionNormalSpacing = 5;
70 // When the title bar is condensed to one row (as when maximized), the New Tab
71 // button and the caption buttons are at similar vertical coordinates, so we
72 // need to reserve a larger, 16 px gap to avoid looking too cluttered.
73 const int kNewTabCaptionCondensedSpacing = 16;
75 // If there are no caption buttons to the right of the New Tab button, we
76 // reserve a small 5px gap, regardless of whether the window is maximized. This
77 // overrides the two previous constants.
78 const int kNewTabNoCaptionButtonsSpacing = 5;
80 // The top 3 px of the tabstrip is shadow; in maximized mode we push this off
81 // the top of the screen so the tabs appear flush against the screen edge.
82 const int kTabstripTopShadowThickness = 3;
84 // How far to indent the tabstrip from the left side of the screen when there
86 const int kTabStripIndent = -6;
88 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
89 // Default extra space between the top of the frame and the top of the window
91 const int kExtraCaption = 2;
93 // Default extra spacing between individual window caption buttons.
94 const int kCaptionButtonSpacing = 2;
96 const int kExtraCaption = 0;
97 const int kCaptionButtonSpacing = 0;
102 ///////////////////////////////////////////////////////////////////////////////
103 // OpaqueBrowserFrameView, public:
105 OpaqueBrowserFrameViewLayout::OpaqueBrowserFrameViewLayout(
106 OpaqueBrowserFrameViewLayoutDelegate* delegate)
107 : delegate_(delegate),
108 leading_button_start_(0),
109 trailing_button_start_(0),
110 minimum_size_for_buttons_(0),
111 has_leading_buttons_(false),
112 has_trailing_buttons_(false),
113 extra_caption_y_(kExtraCaption),
114 window_caption_spacing_(kCaptionButtonSpacing),
115 minimize_button_(NULL),
116 maximize_button_(NULL),
117 restore_button_(NULL),
122 avatar_button_(NULL),
123 new_avatar_button_(NULL) {
124 trailing_buttons_.push_back(views::FRAME_BUTTON_MINIMIZE);
125 trailing_buttons_.push_back(views::FRAME_BUTTON_MAXIMIZE);
126 trailing_buttons_.push_back(views::FRAME_BUTTON_CLOSE);
129 OpaqueBrowserFrameViewLayout::~OpaqueBrowserFrameViewLayout() {}
132 bool OpaqueBrowserFrameViewLayout::ShouldAddDefaultCaptionButtons() {
134 return !win8::IsSingleWindowMetroMode();
139 void OpaqueBrowserFrameViewLayout::SetButtonOrdering(
140 const std::vector<views::FrameButton>& leading_buttons,
141 const std::vector<views::FrameButton>& trailing_buttons) {
142 leading_buttons_ = leading_buttons;
143 trailing_buttons_ = trailing_buttons;
146 gfx::Rect OpaqueBrowserFrameViewLayout::GetBoundsForTabStrip(
147 const gfx::Size& tabstrip_preferred_size,
148 int available_width) const {
149 available_width -= trailing_button_start_;
150 available_width -= leading_button_start_;
152 if (delegate_->GetAdditionalReservedSpaceInTabStrip())
153 available_width -= delegate_->GetAdditionalReservedSpaceInTabStrip();
155 const int caption_spacing = NewTabCaptionSpacing();
156 const int tabstrip_width = available_width - caption_spacing;
157 gfx::Rect bounds(leading_button_start_, GetTabStripInsetsTop(false),
158 std::max(0, tabstrip_width),
159 tabstrip_preferred_size.height());
161 int leading_tabstrip_indent = kTabStripIndent;
162 if (delegate_->ShouldShowAvatar() && !ShouldAvatarBeOnRight()) {
163 if (avatar_label_ && avatar_label_->bounds().width())
164 leading_tabstrip_indent += kAvatarLabelInnerSpacing;
166 leading_tabstrip_indent += kAvatarInnerSpacing;
168 bounds.Inset(leading_tabstrip_indent, 0, 0, 0);
172 gfx::Size OpaqueBrowserFrameViewLayout::GetMinimumSize(
173 int available_width) const {
174 gfx::Size min_size = delegate_->GetBrowserViewMinimumSize();
175 int border_thickness = NonClientBorderThickness();
176 min_size.Enlarge(2 * border_thickness,
177 NonClientTopBorderHeight(false) + border_thickness);
179 // Ensure that we can, at minimum, hold our window controls and avatar icon.
180 min_size.set_width(std::max(min_size.width(), minimum_size_for_buttons_));
182 // Ensure that the minimum width is enough to hold a minimum width tab strip
183 // at its usual insets.
184 if (delegate_->IsTabStripVisible()) {
185 gfx::Size preferred_size = delegate_->GetTabstripPreferredSize();
186 const int min_tabstrip_width = preferred_size.width();
187 const int caption_spacing = NewTabCaptionSpacing();
188 min_size.Enlarge(min_tabstrip_width + caption_spacing, 0);
194 gfx::Rect OpaqueBrowserFrameViewLayout::GetWindowBoundsForClientBounds(
195 const gfx::Rect& client_bounds) const {
196 int top_height = NonClientTopBorderHeight(false);
197 int border_thickness = NonClientBorderThickness();
198 return gfx::Rect(std::max(0, client_bounds.x() - border_thickness),
199 std::max(0, client_bounds.y() - top_height),
200 client_bounds.width() + (2 * border_thickness),
201 client_bounds.height() + top_height + border_thickness);
204 int OpaqueBrowserFrameViewLayout::FrameBorderThickness(bool restored) const {
205 return (!restored && (IsTitleBarCondensed() ||
206 delegate_->IsFullscreen())) ?
207 0 : kFrameBorderThickness;
210 int OpaqueBrowserFrameViewLayout::NonClientBorderThickness() const {
211 // When we fill the screen, we don't show a client edge.
212 return FrameBorderThickness(false) +
213 ((IsTitleBarCondensed() || delegate_->IsFullscreen()) ?
214 0 : views::NonClientFrameView::kClientEdgeThickness);
217 int OpaqueBrowserFrameViewLayout::NonClientTopBorderHeight(
218 bool restored) const {
219 if (delegate_->ShouldShowWindowTitle()) {
220 return std::max(FrameBorderThickness(restored) + delegate_->GetIconSize(),
221 CaptionButtonY(restored) + kCaptionButtonHeightWithPadding) +
222 TitlebarBottomThickness(restored);
225 int thickness = FrameBorderThickness(restored);
226 if (!restored && delegate_->IsTabStripVisible() &&
227 (!delegate_->ShouldLeaveOffsetNearTopBorder() || IsTitleBarCondensed())) {
228 thickness -= kTabstripTopShadowThickness;
233 int OpaqueBrowserFrameViewLayout::GetTabStripInsetsTop(bool restored) const {
234 return NonClientTopBorderHeight(restored) + ((!restored &&
235 (!delegate_->ShouldLeaveOffsetNearTopBorder() ||
236 IsTitleBarCondensed() ||
237 delegate_->IsFullscreen())) ?
238 0 : kNonClientRestoredExtraThickness);
241 int OpaqueBrowserFrameViewLayout::TitlebarBottomThickness(bool restored) const {
242 return kTitlebarTopAndBottomEdgeThickness +
243 ((!restored && IsTitleBarCondensed()) ? 0 :
244 views::NonClientFrameView::kClientEdgeThickness);
247 int OpaqueBrowserFrameViewLayout::CaptionButtonY(bool restored) const {
248 // Maximized buttons start at window top, since the window has no border. This
249 // offset is for the image (the actual clickable bounds extend all the way to
250 // the top to take Fitts' Law into account).
251 return ((!restored && IsTitleBarCondensed()) ?
252 FrameBorderThickness(false) :
253 views::NonClientFrameView::kFrameShadowThickness) + extra_caption_y_;
256 gfx::Rect OpaqueBrowserFrameViewLayout::IconBounds() const {
257 return window_icon_bounds_;
260 gfx::Rect OpaqueBrowserFrameViewLayout::CalculateClientAreaBounds(
263 int top_height = NonClientTopBorderHeight(false);
264 int border_thickness = NonClientBorderThickness();
265 return gfx::Rect(border_thickness, top_height,
266 std::max(0, width - (2 * border_thickness)),
267 std::max(0, height - top_height - border_thickness));
270 bool OpaqueBrowserFrameViewLayout::IsTitleBarCondensed() const {
271 // If there are no caption buttons, there is no need to have an uncondensed
272 // title bar. If the window is maximized, the title bar is condensed
273 // regardless of whether there are caption buttons.
274 return !delegate_->ShouldShowCaptionButtons() || delegate_->IsMaximized();
277 ///////////////////////////////////////////////////////////////////////////////
278 // OpaqueBrowserFrameView, private:
280 bool OpaqueBrowserFrameViewLayout::ShouldAvatarBeOnRight() const {
281 // The avatar should be shown either on the end of the left or the beginning
282 // of the right depending on which side has fewer buttons.
283 return trailing_buttons_.size() < leading_buttons_.size();
286 int OpaqueBrowserFrameViewLayout::NewTabCaptionSpacing() const {
287 return has_trailing_buttons_
288 ? (IsTitleBarCondensed() ? kNewTabCaptionCondensedSpacing
289 : kNewTabCaptionNormalSpacing)
290 : kNewTabNoCaptionButtonsSpacing;
293 void OpaqueBrowserFrameViewLayout::LayoutWindowControls(views::View* host) {
294 if (!ShouldAddDefaultCaptionButtons())
297 int caption_y = CaptionButtonY(false);
299 // Keep a list of all buttons that we don't show.
300 std::vector<views::FrameButton> buttons_not_shown;
301 buttons_not_shown.push_back(views::FRAME_BUTTON_MAXIMIZE);
302 buttons_not_shown.push_back(views::FRAME_BUTTON_MINIMIZE);
303 buttons_not_shown.push_back(views::FRAME_BUTTON_CLOSE);
305 if (delegate_->ShouldShowCaptionButtons()) {
306 for (std::vector<views::FrameButton>::const_iterator it =
307 leading_buttons_.begin(); it != leading_buttons_.end(); ++it) {
308 ConfigureButton(host, *it, ALIGN_LEADING, caption_y);
309 buttons_not_shown.erase(
310 std::remove(buttons_not_shown.begin(), buttons_not_shown.end(), *it),
311 buttons_not_shown.end());
314 for (std::vector<views::FrameButton>::const_reverse_iterator it =
315 trailing_buttons_.rbegin(); it != trailing_buttons_.rend(); ++it) {
316 ConfigureButton(host, *it, ALIGN_TRAILING, caption_y);
317 buttons_not_shown.erase(
318 std::remove(buttons_not_shown.begin(), buttons_not_shown.end(), *it),
319 buttons_not_shown.end());
323 for (std::vector<views::FrameButton>::const_iterator it =
324 buttons_not_shown.begin(); it != buttons_not_shown.end(); ++it) {
329 void OpaqueBrowserFrameViewLayout::LayoutTitleBar(views::View* host) {
330 bool use_hidden_icon_location = true;
332 int size = delegate_->GetIconSize();
333 int frame_thickness = FrameBorderThickness(false);
334 bool should_show_icon = delegate_->ShouldShowWindowIcon();
335 bool should_show_title = delegate_->ShouldShowWindowTitle();
337 if (should_show_icon || should_show_title) {
338 use_hidden_icon_location = false;
340 // Our frame border has a different "3D look" than Windows'. Theirs has
341 // a more complex gradient on the top that they push their icon/title
342 // below; then the maximized window cuts this off and the icon/title are
343 // centered in the remaining space. Because the apparent shape of our
344 // border is simpler, using the same positioning makes things look
345 // slightly uncentered with restored windows, so when the window is
346 // restored, instead of calculating the remaining space from below the
347 // frame border, we calculate from below the 3D edge.
348 int unavailable_px_at_top = IsTitleBarCondensed() ?
349 frame_thickness : kTitlebarTopAndBottomEdgeThickness;
350 // When the icon is shorter than the minimum space we reserve for the
351 // caption button, we vertically center it. We want to bias rounding to
352 // put extra space above the icon, since the 3D edge (+ client edge, for
353 // restored windows) below looks (to the eye) more like additional space
354 // than does the 3D edge (or nothing at all, for maximized windows)
355 // above; hence the +1.
356 int y = unavailable_px_at_top + (NonClientTopBorderHeight(false) -
357 unavailable_px_at_top - size -
358 TitlebarBottomThickness(false) + 1) / 2;
360 window_icon_bounds_ = gfx::Rect(leading_button_start_ + kIconLeftSpacing, y,
362 leading_button_start_ += size + kIconLeftSpacing;
363 minimum_size_for_buttons_ += size + kIconLeftSpacing;
366 if (should_show_icon)
367 window_icon_->SetBoundsRect(window_icon_bounds_);
370 window_title_->SetVisible(should_show_title);
371 if (should_show_title) {
372 window_title_->SetText(delegate_->GetWindowTitle());
374 int text_width = std::max(
375 0, host->width() - trailing_button_start_ - kTitleLogoSpacing -
376 leading_button_start_ - kIconTitleSpacing);
377 window_title_->SetBounds(leading_button_start_ + kIconTitleSpacing,
378 window_icon_bounds_.y(),
379 text_width, window_icon_bounds_.height());
380 leading_button_start_ += text_width + kIconTitleSpacing;
384 if (use_hidden_icon_location) {
385 if (has_leading_buttons_) {
386 // There are window button icons on the left. Don't size the hidden window
387 // icon that people can double click on to close the window.
388 window_icon_bounds_ = gfx::Rect();
390 // We set the icon bounds to a small rectangle in the top leading corner
391 // if there are no icons on the leading side.
392 window_icon_bounds_ = gfx::Rect(
393 frame_thickness + kIconLeftSpacing, frame_thickness, size, size);
398 void OpaqueBrowserFrameViewLayout::LayoutNewStyleAvatar(views::View* host) {
399 DCHECK(switches::IsNewProfileManagement());
400 if (!new_avatar_button_)
403 gfx::Size label_size = new_avatar_button_->GetPreferredSize();
404 int button_size_with_offset = kNewAvatarButtonOffset + label_size.width();
406 int button_x = host->width() - trailing_button_start_ -
407 button_size_with_offset;
408 int button_y = CaptionButtonY(false);
410 trailing_button_start_ += button_size_with_offset;
411 minimum_size_for_buttons_ += button_size_with_offset;
413 new_avatar_button_->SetBounds(
417 button_y + kCaptionButtonHeightWithPadding);
420 void OpaqueBrowserFrameViewLayout::LayoutAvatar(views::View* host) {
421 // Even though the avatar is used for both incognito and profiles we always
422 // use the incognito icon to layout the avatar button. The profile icon
423 // can be customized so we can't depend on its size to perform layout.
424 gfx::ImageSkia incognito_icon = delegate_->GetOTRAvatarIcon();
426 bool avatar_on_right = ShouldAvatarBeOnRight();
427 int avatar_bottom = GetTabStripInsetsTop(false) +
428 delegate_->GetTabStripHeight() - kAvatarBottomSpacing;
429 int avatar_restored_y = avatar_bottom - incognito_icon.height();
430 int avatar_x = avatar_on_right ?
431 host->width() - trailing_button_start_ - kAvatarOuterSpacing -
432 incognito_icon.width() :
433 leading_button_start_ + kAvatarOuterSpacing;
434 int avatar_y = IsTitleBarCondensed() ?
435 (NonClientTopBorderHeight(false) + kTabstripTopShadowThickness) :
437 avatar_bounds_.SetRect(
440 incognito_icon.width(),
441 delegate_->ShouldShowAvatar() ? (avatar_bottom - avatar_y) : 0);
442 if (avatar_button_) {
443 avatar_button_->set_button_on_right(avatar_on_right);
444 avatar_button_->SetBoundsRect(avatar_bounds_);
448 avatar_label_->SetLabelOnRight(avatar_on_right);
449 // Space between the bottom of the avatar and the bottom of the avatar
451 const int kAvatarLabelBottomSpacing = 3;
452 gfx::Size label_size = avatar_label_->GetPreferredSize();
453 // The outside edge of the avatar label should be just outside that of the
454 // avatar menu button.
455 int avatar_label_x = avatar_on_right ?
456 (host->width() - trailing_button_start_ - label_size.width()) :
457 leading_button_start_;
458 gfx::Rect label_bounds(
460 avatar_bottom - kAvatarLabelBottomSpacing - label_size.height(),
462 delegate_->ShouldShowAvatar() ? label_size.height() : 0);
463 avatar_label_->SetBoundsRect(label_bounds);
464 edge_offset = label_size.width();
466 edge_offset = kAvatarOuterSpacing + incognito_icon.width();
469 trailing_button_start_ += edge_offset;
471 leading_button_start_ += edge_offset;
473 // We just add the avatar button size to the minimum size because clicking
474 // the avatar label does the same thing as clicking the avatar button.
475 minimum_size_for_buttons_ += kAvatarOuterSpacing + incognito_icon.width();
479 void OpaqueBrowserFrameViewLayout::ConfigureButton(
481 views::FrameButton button_id,
482 ButtonAlignment alignment,
485 case views::FRAME_BUTTON_MINIMIZE: {
486 minimize_button_->SetVisible(true);
487 SetBoundsForButton(host, minimize_button_, alignment, caption_y);
490 case views::FRAME_BUTTON_MAXIMIZE: {
491 // When the window is restored, we show a maximized button; otherwise, we
492 // show a restore button.
493 bool is_restored = !delegate_->IsMaximized() && !delegate_->IsMinimized();
494 views::ImageButton* invisible_button = is_restored ?
495 restore_button_ : maximize_button_;
496 invisible_button->SetVisible(false);
498 views::ImageButton* visible_button = is_restored ?
499 maximize_button_ : restore_button_;
500 visible_button->SetVisible(true);
501 SetBoundsForButton(host, visible_button, alignment, caption_y);
504 case views::FRAME_BUTTON_CLOSE: {
505 close_button_->SetVisible(true);
506 SetBoundsForButton(host, close_button_, alignment, caption_y);
512 void OpaqueBrowserFrameViewLayout::HideButton(views::FrameButton button_id) {
514 case views::FRAME_BUTTON_MINIMIZE:
515 minimize_button_->SetVisible(false);
517 case views::FRAME_BUTTON_MAXIMIZE:
518 restore_button_->SetVisible(false);
519 maximize_button_->SetVisible(false);
521 case views::FRAME_BUTTON_CLOSE:
522 close_button_->SetVisible(false);
527 void OpaqueBrowserFrameViewLayout::SetBoundsForButton(
529 views::ImageButton* button,
530 ButtonAlignment alignment,
532 gfx::Size button_size = button->GetPreferredSize();
534 button->SetImageAlignment(
535 (alignment == ALIGN_LEADING) ?
536 views::ImageButton::ALIGN_RIGHT : views::ImageButton::ALIGN_LEFT,
537 views::ImageButton::ALIGN_BOTTOM);
539 // There should always be the same number of non-shadow pixels visible to the
540 // side of the caption buttons. In maximized mode we extend buttons to the
541 // screen top and the rightmost button to the screen right (or leftmost button
542 // to the screen left, for left-aligned buttons) to obey Fitts' Law.
543 bool title_bar_condensed = IsTitleBarCondensed();
545 // When we are the first button on the leading side and are the close
546 // button, we must flip ourselves, because the close button assets have
547 // a little notch to fit in the rounded frame.
548 button->SetDrawImageMirrored(alignment == ALIGN_LEADING &&
549 !has_leading_buttons_ &&
550 button == close_button_);
551 // If the window is maximized, align the buttons to its upper edge.
552 int extra_height = title_bar_condensed ? extra_caption_y_ : 0;
555 case ALIGN_LEADING: {
556 if (has_leading_buttons_)
557 leading_button_start_ += window_caption_spacing_;
559 // If we're the first button on the left and maximized, add width to the
560 // right hand side of the screen.
561 int extra_width = (title_bar_condensed && !has_leading_buttons_) ?
562 (kFrameBorderThickness -
563 views::NonClientFrameView::kFrameShadowThickness) : 0;
566 leading_button_start_,
567 caption_y - extra_height,
568 button_size.width() + extra_width,
569 button_size.height() + extra_height);
571 leading_button_start_ += extra_width + button_size.width();
572 minimum_size_for_buttons_ += extra_width + button_size.width();
573 has_leading_buttons_ = true;
576 case ALIGN_TRAILING: {
577 if (has_trailing_buttons_)
578 trailing_button_start_ += window_caption_spacing_;
580 // If we're the first button on the right and maximized, add width to the
581 // right hand side of the screen.
582 int extra_width = (title_bar_condensed && !has_trailing_buttons_) ?
583 (kFrameBorderThickness -
584 views::NonClientFrameView::kFrameShadowThickness) : 0;
587 host->width() - trailing_button_start_ - extra_width -
589 caption_y - extra_height,
590 button_size.width() + extra_width,
591 button_size.height() + extra_height);
593 trailing_button_start_ += extra_width + button_size.width();
594 minimum_size_for_buttons_ += extra_width + button_size.width();
595 has_trailing_buttons_ = true;
601 void OpaqueBrowserFrameViewLayout::SetView(int id, views::View* view) {
602 // Why do things this way instead of having an Init() method, where we're
603 // passed the views we'll handle? Because OpaqueBrowserFrameView doesn't own
604 // all the views which are part of it. The avatar stuff, for example, will be
605 // added and removed by the base class of OpaqueBrowserFrameView.
607 case VIEW_ID_MINIMIZE_BUTTON:
609 DCHECK_EQ(std::string(views::ImageButton::kViewClassName),
610 view->GetClassName());
612 minimize_button_ = static_cast<views::ImageButton*>(view);
614 case VIEW_ID_MAXIMIZE_BUTTON:
616 DCHECK_EQ(std::string(views::ImageButton::kViewClassName),
617 view->GetClassName());
619 maximize_button_ = static_cast<views::ImageButton*>(view);
621 case VIEW_ID_RESTORE_BUTTON:
623 DCHECK_EQ(std::string(views::ImageButton::kViewClassName),
624 view->GetClassName());
626 restore_button_ = static_cast<views::ImageButton*>(view);
628 case VIEW_ID_CLOSE_BUTTON:
630 DCHECK_EQ(std::string(views::ImageButton::kViewClassName),
631 view->GetClassName());
633 close_button_ = static_cast<views::ImageButton*>(view);
635 case VIEW_ID_WINDOW_ICON:
638 case VIEW_ID_WINDOW_TITLE:
640 DCHECK_EQ(std::string(views::Label::kViewClassName),
641 view->GetClassName());
643 window_title_ = static_cast<views::Label*>(view);
645 case VIEW_ID_AVATAR_LABEL:
646 avatar_label_ = static_cast<AvatarLabel*>(view);
648 case VIEW_ID_AVATAR_BUTTON:
650 DCHECK_EQ(std::string(AvatarMenuButton::kViewClassName),
651 view->GetClassName());
653 avatar_button_ = static_cast<AvatarMenuButton*>(view);
655 case VIEW_ID_NEW_AVATAR_BUTTON:
656 new_avatar_button_ = view;
659 NOTIMPLEMENTED() << "Unknown view id " << id;
664 ///////////////////////////////////////////////////////////////////////////////
665 // OpaqueBrowserFrameView, views::LayoutManager:
667 void OpaqueBrowserFrameViewLayout::Layout(views::View* host) {
668 // Reset all our data so that everything is invisible.
669 int thickness = FrameBorderThickness(false);
670 leading_button_start_ = thickness;
671 trailing_button_start_ = thickness;
672 minimum_size_for_buttons_ = leading_button_start_ + trailing_button_start_;
673 has_leading_buttons_ = false;
674 has_trailing_buttons_ = false;
676 LayoutWindowControls(host);
677 LayoutTitleBar(host);
679 // We now add a single pixel to the leading spacing. We do this because the
680 // avatar and tab strip start one pixel inward compared to where things start
681 // on the trailing side.
682 leading_button_start_++;
684 if (delegate_->IsRegularOrGuestSession() &&
685 switches::IsNewProfileManagement())
686 LayoutNewStyleAvatar(host);
690 client_view_bounds_ = CalculateClientAreaBounds(
691 host->width(), host->height());
694 gfx::Size OpaqueBrowserFrameViewLayout::GetPreferredSize(views::View* host) {
695 // This is never used; NonClientView::GetPreferredSize() will be called
701 void OpaqueBrowserFrameViewLayout::ViewAdded(views::View* host,
703 SetView(view->id(), view);
706 void OpaqueBrowserFrameViewLayout::ViewRemoved(views::View* host,
708 SetView(view->id(), NULL);