Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / ui / views / frame / opaque_browser_frame_view_layout.cc
blobc34a4b84ec7cca6cbcf9058ee2b62d6ea9244dca
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"
15 #if defined(OS_WIN)
16 #include "win8/util/win8_util.h"
17 #endif // OS_WIN
19 namespace {
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
26 // padding below it.
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
47 // user).
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
82 // is no avatar icon.
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
87 // caption buttons.
88 const int kExtraCaption = 2;
90 // Default extra spacing between individual window caption buttons.
91 const int kCaptionButtonSpacing = 2;
92 #else
93 const int kExtraCaption = 0;
94 const int kCaptionButtonSpacing = 0;
95 #endif
97 } // namespace
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),
115 close_button_(NULL),
116 window_icon_(NULL),
117 window_title_(NULL),
118 avatar_label_(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() {}
128 // static
129 bool OpaqueBrowserFrameViewLayout::ShouldAddDefaultCaptionButtons() {
130 #if defined(OS_WIN)
131 return !win8::IsSingleWindowMetroMode();
132 #endif // OS_WIN
133 return true;
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;
162 else
163 leading_tabstrip_indent += kAvatarInnerSpacing;
165 bounds.Inset(leading_tabstrip_indent, 0, 0, 0);
166 return bounds;
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);
188 return min_size;
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(
255 int width,
256 int height) const {
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())
282 return;
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) {
312 HideButton(*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,
348 size, size);
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_);
356 if (window_title_) {
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();
376 } else {
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_)
388 return;
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(
401 button_x,
402 button_y,
403 label_size.width(),
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) :
423 avatar_restored_y;
424 avatar_bounds_.SetRect(
425 avatar_x,
426 avatar_y,
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_);
433 int edge_offset;
434 if (avatar_label_) {
435 avatar_label_->SetLabelOnRight(avatar_on_right);
436 // Space between the bottom of the avatar and the bottom of the avatar
437 // label.
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(
446 avatar_label_x,
447 avatar_bottom - kAvatarLabelBottomSpacing - label_size.height(),
448 label_size.width(),
449 delegate_->ShouldShowAvatar() ? label_size.height() : 0);
450 avatar_label_->SetBoundsRect(label_bounds);
451 edge_offset = label_size.width();
452 } else {
453 edge_offset = kAvatarOuterSpacing + incognito_icon.width();
455 if (avatar_on_right)
456 trailing_button_start_ += edge_offset;
457 else
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(
467 views::View* host,
468 views::FrameButton button_id,
469 ButtonAlignment alignment,
470 int caption_y) {
471 switch (button_id) {
472 case views::FRAME_BUTTON_MINIMIZE: {
473 minimize_button_->SetVisible(true);
474 SetBoundsForButton(host, minimize_button_, alignment, caption_y);
475 break;
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);
489 break;
491 case views::FRAME_BUTTON_CLOSE: {
492 close_button_->SetVisible(true);
493 SetBoundsForButton(host, close_button_, alignment, caption_y);
494 break;
499 void OpaqueBrowserFrameViewLayout::HideButton(views::FrameButton button_id) {
500 switch (button_id) {
501 case views::FRAME_BUTTON_MINIMIZE:
502 minimize_button_->SetVisible(false);
503 break;
504 case views::FRAME_BUTTON_MAXIMIZE:
505 restore_button_->SetVisible(false);
506 maximize_button_->SetVisible(false);
507 break;
508 case views::FRAME_BUTTON_CLOSE:
509 close_button_->SetVisible(false);
510 break;
514 void OpaqueBrowserFrameViewLayout::SetBoundsForButton(
515 views::View* host,
516 views::ImageButton* button,
517 ButtonAlignment alignment,
518 int caption_y) {
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;
541 switch (alignment) {
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;
552 button->SetBounds(
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;
561 break;
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;
573 button->SetBounds(
574 host->width() - trailing_button_start_ - extra_width -
575 button_size.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;
583 break;
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.
593 switch (id) {
594 case VIEW_ID_MINIMIZE_BUTTON:
595 if (view) {
596 DCHECK_EQ(std::string(views::ImageButton::kViewClassName),
597 view->GetClassName());
599 minimize_button_ = static_cast<views::ImageButton*>(view);
600 break;
601 case VIEW_ID_MAXIMIZE_BUTTON:
602 if (view) {
603 DCHECK_EQ(std::string(views::ImageButton::kViewClassName),
604 view->GetClassName());
606 maximize_button_ = static_cast<views::ImageButton*>(view);
607 break;
608 case VIEW_ID_RESTORE_BUTTON:
609 if (view) {
610 DCHECK_EQ(std::string(views::ImageButton::kViewClassName),
611 view->GetClassName());
613 restore_button_ = static_cast<views::ImageButton*>(view);
614 break;
615 case VIEW_ID_CLOSE_BUTTON:
616 if (view) {
617 DCHECK_EQ(std::string(views::ImageButton::kViewClassName),
618 view->GetClassName());
620 close_button_ = static_cast<views::ImageButton*>(view);
621 break;
622 case VIEW_ID_WINDOW_ICON:
623 window_icon_ = view;
624 break;
625 case VIEW_ID_WINDOW_TITLE:
626 if (view) {
627 DCHECK_EQ(std::string(views::Label::kViewClassName),
628 view->GetClassName());
630 window_title_ = static_cast<views::Label*>(view);
631 break;
632 case VIEW_ID_AVATAR_LABEL:
633 avatar_label_ = static_cast<AvatarLabel*>(view);
634 break;
635 case VIEW_ID_AVATAR_BUTTON:
636 if (view) {
637 DCHECK_EQ(std::string(AvatarMenuButton::kViewClassName),
638 view->GetClassName());
640 avatar_button_ = static_cast<AvatarMenuButton*>(view);
641 break;
642 case VIEW_ID_NEW_AVATAR_BUTTON:
643 new_avatar_button_ = view;
644 break;
645 default:
646 NOTIMPLEMENTED() << "Unknown view id " << id;
647 break;
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);
674 else
675 LayoutAvatar(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
683 // instead.
684 NOTREACHED();
685 return gfx::Size();
688 void OpaqueBrowserFrameViewLayout::ViewAdded(views::View* host,
689 views::View* view) {
690 SetView(view->id(), view);
693 void OpaqueBrowserFrameViewLayout::ViewRemoved(views::View* host,
694 views::View* view) {
695 SetView(view->id(), NULL);