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/basictypes.h"
8 #include "base/command_line.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "chrome/browser/ui/views/avatar_label.h"
11 #include "chrome/browser/ui/views/avatar_menu_button.h"
12 #include "chrome/browser/ui/views/tab_icon_view.h"
13 #include "chrome/browser/ui/views/tabs/tab.h"
14 #include "chrome/common/chrome_switches.h"
15 #include "ui/gfx/image/image_skia.h"
16 #include "ui/gfx/image/image_skia_rep.h"
17 #include "ui/gfx/text_constants.h"
18 #include "ui/views/controls/button/image_button.h"
19 #include "ui/views/controls/button/menu_button.h"
20 #include "ui/views/controls/label.h"
21 #include "ui/views/test/views_test_base.h"
27 const int kWidth
= 500;
29 class TestLayoutDelegate
: public OpaqueBrowserFrameViewLayoutDelegate
{
39 : show_avatar_(false),
40 show_caption_buttons_(true),
41 window_state_(STATE_NORMAL
) {
44 virtual ~TestLayoutDelegate() {}
46 void SetWindowTitle(const base::string16
& title
) {
47 window_title_
= title
;
50 void SetShouldShowAvatar(bool show_avatar
) {
51 show_avatar_
= show_avatar
;
54 void SetShouldShowCaptionButtons(bool show_caption_buttons
) {
55 show_caption_buttons_
= show_caption_buttons
;
58 void SetWindowState(WindowState state
) {
59 window_state_
= state
;
62 // OpaqueBrowserFrameViewLayoutDelegate overrides:
64 virtual bool ShouldShowWindowIcon() const OVERRIDE
{
65 return !window_title_
.empty();
68 virtual bool ShouldShowWindowTitle() const OVERRIDE
{
69 return !window_title_
.empty();
72 virtual base::string16
GetWindowTitle() const OVERRIDE
{
76 virtual int GetIconSize() const OVERRIDE
{
77 // The value on linux_aura and non-aura windows.
81 virtual bool ShouldLeaveOffsetNearTopBorder() const OVERRIDE
{
82 return !IsMaximized();
85 virtual gfx::Size
GetBrowserViewMinimumSize() const OVERRIDE
{
86 // Taken from a calculation in BrowserViewLayout.
87 return gfx::Size(168, 64);
90 virtual bool ShouldShowCaptionButtons() const OVERRIDE
{
91 return show_caption_buttons_
;
94 virtual bool ShouldShowAvatar() const OVERRIDE
{
98 virtual bool IsRegularOrGuestSession() const OVERRIDE
{
102 virtual gfx::ImageSkia
GetOTRAvatarIcon() const OVERRIDE
{
103 // The calculations depend on the size of the OTR resource, and chromeos
104 // uses a different sized image, so hard code the size of the current
105 // windows/linux one.
106 gfx::ImageSkiaRep
rep(gfx::Size(40, 29), 1.0f
);
107 gfx::ImageSkia
image(rep
);
111 virtual bool IsMaximized() const OVERRIDE
{
112 return window_state_
== STATE_MAXIMIZED
;
115 virtual bool IsMinimized() const OVERRIDE
{
116 return window_state_
== STATE_MINIMIZED
;
119 virtual bool IsFullscreen() const OVERRIDE
{
120 return window_state_
== STATE_FULLSCREEN
;
123 virtual bool IsTabStripVisible() const OVERRIDE
{
124 return window_title_
.empty();
127 virtual int GetTabStripHeight() const OVERRIDE
{
128 return IsTabStripVisible() ? Tab::GetMinimumUnselectedSize().height() : 0;
131 virtual int GetAdditionalReservedSpaceInTabStrip() const OVERRIDE
{
135 virtual gfx::Size
GetTabstripPreferredSize() const OVERRIDE
{
136 // Measured from Tabstrip::GetPreferredSize().
137 return IsTabStripVisible() ? gfx::Size(78, 29) : gfx::Size(0, 0);
141 base::string16 window_title_
;
143 bool show_caption_buttons_
;
144 WindowState window_state_
;
146 DISALLOW_COPY_AND_ASSIGN(TestLayoutDelegate
);
151 class OpaqueBrowserFrameViewLayoutTest
: public views::ViewsTestBase
{
153 OpaqueBrowserFrameViewLayoutTest() {}
154 virtual ~OpaqueBrowserFrameViewLayoutTest() {}
156 virtual void SetUp() OVERRIDE
{
157 views::ViewsTestBase::SetUp();
159 delegate_
.reset(new TestLayoutDelegate
);
160 layout_manager_
= new OpaqueBrowserFrameViewLayout(delegate_
.get());
161 layout_manager_
->set_extra_caption_y(0);
162 layout_manager_
->set_window_caption_spacing(0);
163 widget_
= new Widget
;
164 widget_
->Init(CreateParams(Widget::InitParams::TYPE_POPUP
));
165 root_view_
= widget_
->GetRootView();
166 root_view_
->SetSize(gfx::Size(kWidth
, kWidth
));
167 root_view_
->SetLayoutManager(layout_manager_
);
169 // Add the caption buttons. We use fake images because we're modeling the
170 // Windows assets here, while the linux version uses differently sized
173 // TODO(erg): In a follow up patch, separate these sizes out into virtual
174 // accessors so we can test both the windows and linux behaviours once we
175 // start modifying the code.
176 minimize_button_
= InitWindowCaptionButton(
177 VIEW_ID_MINIMIZE_BUTTON
, gfx::Size(26, 18));
178 maximize_button_
= InitWindowCaptionButton(
179 VIEW_ID_MAXIMIZE_BUTTON
, gfx::Size(25, 18));
180 restore_button_
= InitWindowCaptionButton(
181 VIEW_ID_RESTORE_BUTTON
, gfx::Size(25, 18));
182 close_button_
= InitWindowCaptionButton(
183 VIEW_ID_CLOSE_BUTTON
, gfx::Size(43, 18));
186 virtual void TearDown() OVERRIDE
{
189 views::ViewsTestBase::TearDown();
193 views::ImageButton
* InitWindowCaptionButton(ViewID view_id
,
194 const gfx::Size
& size
) {
195 views::ImageButton
* button
= new views::ImageButton(NULL
);
196 gfx::ImageSkiaRep
rep(size
, 1.0f
);
197 gfx::ImageSkia
image(rep
);
198 button
->SetImage(views::CustomButton::STATE_NORMAL
, &image
);
199 button
->set_id(view_id
);
200 root_view_
->AddChildView(button
);
204 void AddWindowTitleIcons() {
205 tab_icon_view_
= new TabIconView(NULL
, NULL
);
206 tab_icon_view_
->set_is_light(true);
207 tab_icon_view_
->set_id(VIEW_ID_WINDOW_ICON
);
208 root_view_
->AddChildView(tab_icon_view_
);
210 window_title_
= new views::Label(delegate_
->GetWindowTitle());
211 window_title_
->SetVisible(delegate_
->ShouldShowWindowTitle());
212 window_title_
->SetEnabledColor(SK_ColorWHITE
);
213 window_title_
->SetBackgroundColor(0x00000000);
214 window_title_
->SetHorizontalAlignment(gfx::ALIGN_LEFT
);
215 window_title_
->set_id(VIEW_ID_WINDOW_TITLE
);
216 root_view_
->AddChildView(window_title_
);
219 void AddAvatarButton() {
220 menu_button_
= new AvatarMenuButton(NULL
, false);
221 menu_button_
->set_id(VIEW_ID_AVATAR_BUTTON
);
222 delegate_
->SetShouldShowAvatar(true);
223 root_view_
->AddChildView(menu_button_
);
226 void AddAvatarLabel() {
227 avatar_label_
= new AvatarLabel(NULL
);
228 avatar_label_
->set_id(VIEW_ID_AVATAR_LABEL
);
229 root_view_
->AddChildView(avatar_label_
);
231 // The avatar label should only be used together with the avatar button.
235 void AddNewAvatarButton() {
237 new views::MenuButton(NULL
, base::string16(), NULL
, false);
238 new_avatar_button_
->set_id(VIEW_ID_NEW_AVATAR_BUTTON
);
239 root_view_
->AddChildView(new_avatar_button_
);
242 void ExpectBasicWindowBounds() {
243 EXPECT_EQ("428,1 25x18", maximize_button_
->bounds().ToString());
244 EXPECT_EQ("402,1 26x18", minimize_button_
->bounds().ToString());
245 EXPECT_EQ("0,0 0x0", restore_button_
->bounds().ToString());
246 EXPECT_EQ("453,1 43x18", close_button_
->bounds().ToString());
250 views::View
* root_view_
;
251 OpaqueBrowserFrameViewLayout
* layout_manager_
;
252 scoped_ptr
<TestLayoutDelegate
> delegate_
;
255 views::ImageButton
* minimize_button_
;
256 views::ImageButton
* maximize_button_
;
257 views::ImageButton
* restore_button_
;
258 views::ImageButton
* close_button_
;
260 TabIconView
* tab_icon_view_
;
261 views::Label
* window_title_
;
263 AvatarLabel
* avatar_label_
;
264 AvatarMenuButton
* menu_button_
;
265 views::MenuButton
* new_avatar_button_
;
267 DISALLOW_COPY_AND_ASSIGN(OpaqueBrowserFrameViewLayoutTest
);
270 TEST_F(OpaqueBrowserFrameViewLayoutTest
, BasicWindow
) {
271 // Tests the layout of a default chrome window with no avatars, no window
272 // titles, and a tabstrip.
273 root_view_
->Layout();
275 ExpectBasicWindowBounds();
277 // After some visual inspection, it really does look like the tabstrip is
278 // initally positioned out of our view.
279 EXPECT_EQ("-1,13 398x29",
280 layout_manager_
->GetBoundsForTabStrip(
281 delegate_
->GetTabstripPreferredSize(), kWidth
).ToString());
282 EXPECT_EQ("261x73", layout_manager_
->GetMinimumSize(kWidth
).ToString());
284 // A normal window with no window icon still produces icon bounds for
285 // Windows, which has a hidden icon that a user can double click on to close
287 EXPECT_EQ("6,4 17x17", layout_manager_
->IconBounds().ToString());
290 TEST_F(OpaqueBrowserFrameViewLayoutTest
, BasicWindowMaximized
) {
291 // Tests the layout of a default chrome window with no avatars, no window
292 // titles, and a tabstrip, but maximized this time.
293 delegate_
->SetWindowState(TestLayoutDelegate::STATE_MAXIMIZED
);
294 root_view_
->Layout();
296 // Note how the bounds start at the exact top of the window while maximized
297 // while they start 1 pixel below when unmaximized.
298 EXPECT_EQ("0,0 0x0", maximize_button_
->bounds().ToString());
299 EXPECT_EQ("403,0 26x18", minimize_button_
->bounds().ToString());
300 EXPECT_EQ("429,0 25x18", restore_button_
->bounds().ToString());
301 EXPECT_EQ("454,0 46x18", close_button_
->bounds().ToString());
303 EXPECT_EQ("-5,-3 392x29",
304 layout_manager_
->GetBoundsForTabStrip(
305 delegate_
->GetTabstripPreferredSize(), kWidth
).ToString());
306 EXPECT_EQ("262x61", layout_manager_
->GetMinimumSize(kWidth
).ToString());
308 // In the maximized case, OpaqueBrowserFrameView::NonClientHitTest() uses
309 // this rect, extended to the top left corner of the window.
310 EXPECT_EQ("2,0 17x17", layout_manager_
->IconBounds().ToString());
313 TEST_F(OpaqueBrowserFrameViewLayoutTest
, MaximizedWithYOffset
) {
314 // Tests the layout of a basic chrome window with the caption buttons slightly
315 // offset from the top of the screen (as they are on Linux).
316 layout_manager_
->set_extra_caption_y(2);
317 delegate_
->SetWindowState(TestLayoutDelegate::STATE_MAXIMIZED
);
318 root_view_
->Layout();
320 // Note how the bounds start at the exact top of the window, DESPITE the
321 // caption Y offset of 2. This ensures that we obey Fitts' Law (the buttons
322 // are clickable on the top edge of the screen). However, the buttons are 2
323 // pixels taller, so the images appear to be offset by 2 pixels.
324 EXPECT_EQ("0,0 0x0", maximize_button_
->bounds().ToString());
325 EXPECT_EQ("403,0 26x20", minimize_button_
->bounds().ToString());
326 EXPECT_EQ("429,0 25x20", restore_button_
->bounds().ToString());
327 EXPECT_EQ("454,0 46x20", close_button_
->bounds().ToString());
329 EXPECT_EQ("-5,-3 392x29",
330 layout_manager_
->GetBoundsForTabStrip(
331 delegate_
->GetTabstripPreferredSize(), kWidth
).ToString());
332 EXPECT_EQ("262x61", layout_manager_
->GetMinimumSize(kWidth
).ToString());
334 // In the maximized case, OpaqueBrowserFrameView::NonClientHitTest() uses
335 // this rect, extended to the top left corner of the window.
336 EXPECT_EQ("2,0 17x17", layout_manager_
->IconBounds().ToString());
339 TEST_F(OpaqueBrowserFrameViewLayoutTest
, WindowButtonsOnLeft
) {
340 // Tests the layout of a chrome window with caption buttons on the left.
341 std::vector
<views::FrameButton
> leading_buttons
;
342 std::vector
<views::FrameButton
> trailing_buttons
;
343 leading_buttons
.push_back(views::FRAME_BUTTON_CLOSE
);
344 leading_buttons
.push_back(views::FRAME_BUTTON_MINIMIZE
);
345 leading_buttons
.push_back(views::FRAME_BUTTON_MAXIMIZE
);
346 layout_manager_
->SetButtonOrdering(leading_buttons
, trailing_buttons
);
347 root_view_
->Layout();
349 EXPECT_EQ("73,1 25x18", maximize_button_
->bounds().ToString());
350 EXPECT_EQ("47,1 26x18", minimize_button_
->bounds().ToString());
351 EXPECT_EQ("0,0 0x0", restore_button_
->bounds().ToString());
352 EXPECT_EQ("4,1 43x18", close_button_
->bounds().ToString());
354 EXPECT_EQ("93,13 398x29",
355 layout_manager_
->GetBoundsForTabStrip(
356 delegate_
->GetTabstripPreferredSize(), kWidth
).ToString());
357 EXPECT_EQ("261x73", layout_manager_
->GetMinimumSize(kWidth
).ToString());
359 // If the buttons are on the left, there should be no hidden icon for the user
361 EXPECT_EQ("0,0 0x0", layout_manager_
->IconBounds().ToString());
364 TEST_F(OpaqueBrowserFrameViewLayoutTest
, WithoutCaptionButtons
) {
365 // Tests the layout of a default chrome window with no caption buttons (which
366 // should force the tab strip to be condensed).
367 delegate_
->SetShouldShowCaptionButtons(false);
368 root_view_
->Layout();
370 EXPECT_EQ("0,0 0x0", maximize_button_
->bounds().ToString());
371 EXPECT_EQ("0,0 0x0", minimize_button_
->bounds().ToString());
372 EXPECT_EQ("0,0 0x0", restore_button_
->bounds().ToString());
373 EXPECT_EQ("0,0 0x0", close_button_
->bounds().ToString());
375 EXPECT_EQ("-5,-3 500x29",
376 layout_manager_
->GetBoundsForTabStrip(
377 delegate_
->GetTabstripPreferredSize(), kWidth
).ToString());
378 EXPECT_EQ("251x61", layout_manager_
->GetMinimumSize(kWidth
).ToString());
380 // A normal window with no window icon still produces icon bounds for
381 // Windows, which has a hidden icon that a user can double click on to close
383 EXPECT_EQ("2,0 17x17", layout_manager_
->IconBounds().ToString());
386 TEST_F(OpaqueBrowserFrameViewLayoutTest
, MaximizedWithoutCaptionButtons
) {
387 // Tests the layout of a maximized chrome window with no caption buttons.
388 delegate_
->SetWindowState(TestLayoutDelegate::STATE_MAXIMIZED
);
389 delegate_
->SetShouldShowCaptionButtons(false);
390 root_view_
->Layout();
392 EXPECT_EQ("0,0 0x0", maximize_button_
->bounds().ToString());
393 EXPECT_EQ("0,0 0x0", minimize_button_
->bounds().ToString());
394 EXPECT_EQ("0,0 0x0", restore_button_
->bounds().ToString());
395 EXPECT_EQ("0,0 0x0", close_button_
->bounds().ToString());
397 EXPECT_EQ("-5,-3 500x29",
398 layout_manager_
->GetBoundsForTabStrip(
399 delegate_
->GetTabstripPreferredSize(), kWidth
).ToString());
400 EXPECT_EQ("251x61", layout_manager_
->GetMinimumSize(kWidth
).ToString());
402 // In the maximized case, OpaqueBrowserFrameView::NonClientHitTest() uses
403 // this rect, extended to the top left corner of the window.
404 EXPECT_EQ("2,0 17x17", layout_manager_
->IconBounds().ToString());
407 TEST_F(OpaqueBrowserFrameViewLayoutTest
, WithWindowTitleAndIcon
) {
408 // Tests the layout of pop up windows.
409 delegate_
->SetWindowTitle(base::ASCIIToUTF16("Window Title"));
410 AddWindowTitleIcons();
411 root_view_
->Layout();
413 // We should have the right hand side should match the BasicWindow case.
414 ExpectBasicWindowBounds();
416 // Check the location of the tab icon and window title.
417 EXPECT_EQ("6,3 17x17", tab_icon_view_
->bounds().ToString());
418 EXPECT_EQ("27,3 370x17", window_title_
->bounds().ToString());
421 TEST_F(OpaqueBrowserFrameViewLayoutTest
, WindowWithAvatar
) {
422 // Tests a normal tabstrip window with an avatar icon.
424 root_view_
->Layout();
426 ExpectBasicWindowBounds();
428 // Check the location of the avatar
429 EXPECT_EQ("7,11 40x29", menu_button_
->bounds().ToString());
430 EXPECT_EQ("45,13 352x29",
431 layout_manager_
->GetBoundsForTabStrip(
432 delegate_
->GetTabstripPreferredSize(), kWidth
).ToString());
433 EXPECT_EQ("261x73", layout_manager_
->GetMinimumSize(kWidth
).ToString());
436 TEST_F(OpaqueBrowserFrameViewLayoutTest
, WindowWithAvatarWithButtonsOnLeft
) {
437 // Tests the layout of a chrome window with an avatar icon and caption buttons
438 // on the left. The avatar icon should therefore be on the right.
439 // AddAvatarLabel() also adds the avatar button.
441 std::vector
<views::FrameButton
> leading_buttons
;
442 std::vector
<views::FrameButton
> trailing_buttons
;
443 leading_buttons
.push_back(views::FRAME_BUTTON_CLOSE
);
444 leading_buttons
.push_back(views::FRAME_BUTTON_MINIMIZE
);
445 leading_buttons
.push_back(views::FRAME_BUTTON_MAXIMIZE
);
446 layout_manager_
->SetButtonOrdering(leading_buttons
, trailing_buttons
);
447 root_view_
->Layout();
449 EXPECT_EQ("73,1 25x18", maximize_button_
->bounds().ToString());
450 EXPECT_EQ("47,1 26x18", minimize_button_
->bounds().ToString());
451 EXPECT_EQ("0,0 0x0", restore_button_
->bounds().ToString());
452 EXPECT_EQ("4,1 43x18", close_button_
->bounds().ToString());
454 // Check the location of the avatar
455 EXPECT_EQ("454,11 40x29", menu_button_
->bounds().ToString());
457 // Check the tab strip bounds.
458 gfx::Rect tab_strip_bounds
= layout_manager_
->GetBoundsForTabStrip(
459 delegate_
->GetTabstripPreferredSize(), kWidth
);
460 EXPECT_GT(tab_strip_bounds
.x(), maximize_button_
->bounds().x());
461 EXPECT_GT(maximize_button_
->bounds().right(), tab_strip_bounds
.x());
462 EXPECT_EQ(13, tab_strip_bounds
.y());
463 EXPECT_EQ(29, tab_strip_bounds
.height());
464 EXPECT_GT(avatar_label_
->bounds().x(), tab_strip_bounds
.right());
465 EXPECT_EQ("261x73", layout_manager_
->GetMinimumSize(kWidth
).ToString());
467 // Check the relative location of the avatar label to the avatar. The right
468 // end of the avatar label should be slightly to the right of the right end of
470 EXPECT_GT(avatar_label_
->bounds().right(), menu_button_
->bounds().right());
471 EXPECT_GT(menu_button_
->bounds().x(), avatar_label_
->bounds().x());
472 EXPECT_GT(menu_button_
->bounds().bottom(),
473 avatar_label_
->bounds().bottom());
474 EXPECT_GT(avatar_label_
->bounds().y(), menu_button_
->bounds().y());
476 // This means that the menu will pop out facing the left (if it were to face
477 // the right, it would go outside the window frame and be clipped).
478 EXPECT_TRUE(menu_button_
->button_on_right());
480 // If the buttons are on the left, there should be no hidden icon for the user
482 EXPECT_EQ("0,0 0x0", layout_manager_
->IconBounds().ToString());
485 TEST_F(OpaqueBrowserFrameViewLayoutTest
,
486 WindowWithAvatarWithoutCaptionButtonsOnLeft
) {
487 // Tests the layout of a chrome window with an avatar icon and no caption
488 // buttons. However, the caption buttons *would* be on the left if they
489 // weren't hidden, and therefore, the avatar icon should be on the right.
490 // The lack of caption buttons should force the tab strip to be condensed.
492 std::vector
<views::FrameButton
> leading_buttons
;
493 std::vector
<views::FrameButton
> trailing_buttons
;
494 leading_buttons
.push_back(views::FRAME_BUTTON_CLOSE
);
495 leading_buttons
.push_back(views::FRAME_BUTTON_MINIMIZE
);
496 leading_buttons
.push_back(views::FRAME_BUTTON_MAXIMIZE
);
497 layout_manager_
->SetButtonOrdering(leading_buttons
, trailing_buttons
);
498 delegate_
->SetShouldShowCaptionButtons(false);
499 root_view_
->Layout();
501 EXPECT_EQ("0,0 0x0", maximize_button_
->bounds().ToString());
502 EXPECT_EQ("0,0 0x0", minimize_button_
->bounds().ToString());
503 EXPECT_EQ("0,0 0x0", restore_button_
->bounds().ToString());
504 EXPECT_EQ("0,0 0x0", close_button_
->bounds().ToString());
506 // Check the location of the avatar
507 EXPECT_EQ("458,0 40x24", menu_button_
->bounds().ToString());
508 EXPECT_EQ("-5,-3 458x29",
509 layout_manager_
->GetBoundsForTabStrip(
510 delegate_
->GetTabstripPreferredSize(), kWidth
).ToString());
511 EXPECT_EQ("251x61", layout_manager_
->GetMinimumSize(kWidth
).ToString());
513 // A normal window with no window icon still produces icon bounds for
514 // Windows, which has a hidden icon that a user can double click on to close
516 EXPECT_EQ("2,0 17x17", layout_manager_
->IconBounds().ToString());
519 TEST_F(OpaqueBrowserFrameViewLayoutTest
, WindowWithNewAvatar
) {
520 CommandLine::ForCurrentProcess()->AppendSwitch(
521 switches::kNewProfileManagement
);
523 // Tests a normal tabstrip window with the new style avatar icon.
524 AddNewAvatarButton();
525 root_view_
->Layout();
527 ExpectBasicWindowBounds();
529 // Check the location of the caption button
530 EXPECT_EQ("385,1 12x20", new_avatar_button_
->bounds().ToString());
531 // The basic window bounds are (-1, 13 398x29). There should not be an icon
532 // avatar in the left, and the new avatar button has an offset of 5 to its
534 EXPECT_EQ("-1,13 381x29",
535 layout_manager_
->GetBoundsForTabStrip(
536 delegate_
->GetTabstripPreferredSize(), kWidth
).ToString());
537 EXPECT_EQ("261x73", layout_manager_
->GetMinimumSize(kWidth
).ToString());
540 TEST_F(OpaqueBrowserFrameViewLayoutTest
, WindowWithAvatarLabelAndButtonOnLeft
) {
542 root_view_
->Layout();
544 ExpectBasicWindowBounds();
546 // Check the location of the avatar label relative to the avatar button if
547 // both are displayed on the left side.
548 // The label height and width depends on the font size and the text displayed.
549 // This may possibly change, so we don't test it here.
550 EXPECT_EQ(menu_button_
->bounds().x() - 2, avatar_label_
->bounds().x());
552 menu_button_
->bounds().bottom() - 3 - avatar_label_
->bounds().height(),
553 avatar_label_
->bounds().y());