OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/ui/views/frame/opaque_browser_frame_view.h" | 5 #include "chrome/browser/ui/views/frame/opaque_browser_frame_view.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
(...skipping 24 matching lines...) Expand all Loading... |
35 #include "ui/gfx/canvas_skia.h" | 35 #include "ui/gfx/canvas_skia.h" |
36 #include "ui/gfx/font.h" | 36 #include "ui/gfx/font.h" |
37 #include "ui/gfx/image/image.h" | 37 #include "ui/gfx/image/image.h" |
38 #include "ui/gfx/path.h" | 38 #include "ui/gfx/path.h" |
39 #include "ui/views/controls/button/image_button.h" | 39 #include "ui/views/controls/button/image_button.h" |
40 #include "ui/views/controls/image_view.h" | 40 #include "ui/views/controls/image_view.h" |
41 #include "ui/views/widget/root_view.h" | 41 #include "ui/views/widget/root_view.h" |
42 #include "ui/views/window/frame_background.h" | 42 #include "ui/views/window/frame_background.h" |
43 #include "ui/views/window/window_shape.h" | 43 #include "ui/views/window/window_shape.h" |
44 | 44 |
45 #if defined(USE_AURA) | |
46 #include "ui/aura/aura_switches.h" | |
47 #endif | |
48 | |
49 #if defined(USE_VIRTUAL_KEYBOARD) | 45 #if defined(USE_VIRTUAL_KEYBOARD) |
50 #include "chrome/browser/ui/virtual_keyboard/virtual_keyboard_manager.h" | 46 #include "chrome/browser/ui/virtual_keyboard/virtual_keyboard_manager.h" |
51 #endif | 47 #endif |
52 | 48 |
53 using content::WebContents; | 49 using content::WebContents; |
54 | 50 |
55 namespace { | 51 namespace { |
56 | 52 |
57 // The frame border is only visible in restored mode and is hardcoded to 4 px on | 53 // The frame border is only visible in restored mode and is hardcoded to 4 px on |
58 // each side regardless of the system window border size. | 54 // each side regardless of the system window border size. |
(...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
492 return FrameBorderThickness(false) - kTopResizeAdjust; | 488 return FrameBorderThickness(false) - kTopResizeAdjust; |
493 } | 489 } |
494 | 490 |
495 int OpaqueBrowserFrameView::NonClientBorderThickness() const { | 491 int OpaqueBrowserFrameView::NonClientBorderThickness() const { |
496 // When we fill the screen, we don't show a client edge. | 492 // When we fill the screen, we don't show a client edge. |
497 return FrameBorderThickness(false) + | 493 return FrameBorderThickness(false) + |
498 ((frame()->IsMaximized() || frame()->IsFullscreen()) ? | 494 ((frame()->IsMaximized() || frame()->IsFullscreen()) ? |
499 0 : kClientEdgeThickness); | 495 0 : kClientEdgeThickness); |
500 } | 496 } |
501 | 497 |
502 void OpaqueBrowserFrameView::ModifyMaximizedFramePainting( | |
503 int* theme_offset, | |
504 SkBitmap** theme_frame, | |
505 SkBitmap** left_corner, | |
506 SkBitmap** right_corner) { | |
507 } | |
508 | |
509 int OpaqueBrowserFrameView::CaptionButtonY(bool restored) const { | 498 int OpaqueBrowserFrameView::CaptionButtonY(bool restored) const { |
510 // Maximized buttons start at window top so that even if their images aren't | 499 // Maximized buttons start at window top so that even if their images aren't |
511 // drawn flush with the screen edge, they still obey Fitts' Law. | 500 // drawn flush with the screen edge, they still obey Fitts' Law. |
512 return (!restored && frame()->IsMaximized()) ? | 501 return (!restored && frame()->IsMaximized()) ? |
513 FrameBorderThickness(false) : kFrameShadowThickness; | 502 FrameBorderThickness(false) : kFrameShadowThickness; |
514 } | 503 } |
515 | 504 |
516 int OpaqueBrowserFrameView::TitlebarBottomThickness(bool restored) const { | 505 int OpaqueBrowserFrameView::TitlebarBottomThickness(bool restored) const { |
517 return kTitlebarTopAndBottomEdgeThickness + | 506 return kTitlebarTopAndBottomEdgeThickness + |
518 ((!restored && frame()->IsMaximized()) ? 0 : kClientEdgeThickness); | 507 ((!restored && frame()->IsMaximized()) ? 0 : kClientEdgeThickness); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
566 frame_background_->set_theme_bitmap(GetFrameBitmap()); | 555 frame_background_->set_theme_bitmap(GetFrameBitmap()); |
567 frame_background_->set_theme_overlay_bitmap(GetFrameOverlayBitmap()); | 556 frame_background_->set_theme_overlay_bitmap(GetFrameOverlayBitmap()); |
568 frame_background_->set_top_area_height(GetTopAreaHeight()); | 557 frame_background_->set_top_area_height(GetTopAreaHeight()); |
569 | 558 |
570 ui::ThemeProvider* tp = GetThemeProvider(); | 559 ui::ThemeProvider* tp = GetThemeProvider(); |
571 frame_background_->SetSideImages( | 560 frame_background_->SetSideImages( |
572 tp->GetBitmapNamed(IDR_WINDOW_LEFT_SIDE), | 561 tp->GetBitmapNamed(IDR_WINDOW_LEFT_SIDE), |
573 tp->GetBitmapNamed(IDR_WINDOW_TOP_CENTER), | 562 tp->GetBitmapNamed(IDR_WINDOW_TOP_CENTER), |
574 tp->GetBitmapNamed(IDR_WINDOW_RIGHT_SIDE), | 563 tp->GetBitmapNamed(IDR_WINDOW_RIGHT_SIDE), |
575 tp->GetBitmapNamed(IDR_WINDOW_BOTTOM_CENTER)); | 564 tp->GetBitmapNamed(IDR_WINDOW_BOTTOM_CENTER)); |
576 #if defined(USE_AURA) | |
577 // TODO(jamescook): Remove this when Aura defaults to its own window frame, | |
578 // BrowserNonClientFrameViewAura. Until then, use custom square corners to | |
579 // avoid performance penalties associated with transparent layers. | |
580 frame_background_->SetCornerImages( | |
581 tp->GetBitmapNamed(IDR_AURA_WINDOW_TOP_LEFT), | |
582 tp->GetBitmapNamed(IDR_AURA_WINDOW_TOP_RIGHT), | |
583 tp->GetBitmapNamed(IDR_AURA_WINDOW_BOTTOM_LEFT), | |
584 tp->GetBitmapNamed(IDR_AURA_WINDOW_BOTTOM_RIGHT)); | |
585 #else | |
586 frame_background_->SetCornerImages( | 565 frame_background_->SetCornerImages( |
587 tp->GetBitmapNamed(IDR_WINDOW_TOP_LEFT_CORNER), | 566 tp->GetBitmapNamed(IDR_WINDOW_TOP_LEFT_CORNER), |
588 tp->GetBitmapNamed(IDR_WINDOW_TOP_RIGHT_CORNER), | 567 tp->GetBitmapNamed(IDR_WINDOW_TOP_RIGHT_CORNER), |
589 tp->GetBitmapNamed(IDR_WINDOW_BOTTOM_LEFT_CORNER), | 568 tp->GetBitmapNamed(IDR_WINDOW_BOTTOM_LEFT_CORNER), |
590 tp->GetBitmapNamed(IDR_WINDOW_BOTTOM_RIGHT_CORNER)); | 569 tp->GetBitmapNamed(IDR_WINDOW_BOTTOM_RIGHT_CORNER)); |
591 #endif | |
592 frame_background_->PaintRestored(canvas, this); | 570 frame_background_->PaintRestored(canvas, this); |
593 | 571 |
594 // Note: When we don't have a toolbar, we need to draw some kind of bottom | 572 // Note: When we don't have a toolbar, we need to draw some kind of bottom |
595 // edge here. Because the App Window graphics we use for this have an | 573 // edge here. Because the App Window graphics we use for this have an |
596 // attached client edge and their sizing algorithm is a little involved, we do | 574 // attached client edge and their sizing algorithm is a little involved, we do |
597 // all this in PaintRestoredClientEdge(). | 575 // all this in PaintRestoredClientEdge(). |
598 } | 576 } |
599 | 577 |
600 void OpaqueBrowserFrameView::PaintMaximizedFrameBorder(gfx::Canvas* canvas) { | 578 void OpaqueBrowserFrameView::PaintMaximizedFrameBorder(gfx::Canvas* canvas) { |
601 frame_background_->set_frame_color(GetFrameColor()); | 579 frame_background_->set_frame_color(GetFrameColor()); |
602 frame_background_->set_theme_bitmap(GetFrameBitmap()); | 580 frame_background_->set_theme_bitmap(GetFrameBitmap()); |
603 frame_background_->set_theme_overlay_bitmap(GetFrameOverlayBitmap()); | 581 frame_background_->set_theme_overlay_bitmap(GetFrameOverlayBitmap()); |
604 frame_background_->set_top_area_height(GetTopAreaHeight()); | 582 frame_background_->set_top_area_height(GetTopAreaHeight()); |
605 | 583 |
606 // Allow customization of these attributes. | |
607 SkBitmap* theme_frame = NULL; | |
608 SkBitmap* left = NULL; | |
609 SkBitmap* right = NULL; | |
610 int top_offset = 0; | |
611 ModifyMaximizedFramePainting(&top_offset, &theme_frame, &left, &right); | |
612 frame_background_->SetMaximizedCorners(left, right, top_offset); | |
613 // If user has a theme installed, theme_frame would be NULL and | |
614 // frame_background_ is unchanged. | |
615 if (theme_frame) | |
616 frame_background_->set_theme_bitmap(theme_frame); | |
617 | |
618 // Theme frame must be aligned with the tabstrip as if we were | 584 // Theme frame must be aligned with the tabstrip as if we were |
619 // in restored mode. Note that the top of the tabstrip is | 585 // in restored mode. Note that the top of the tabstrip is |
620 // kTabstripTopShadowThickness px off the top of the screen. | 586 // kTabstripTopShadowThickness px off the top of the screen. |
621 int theme_background_y = -(GetHorizontalTabStripVerticalOffset(true) + | 587 int theme_background_y = -(GetHorizontalTabStripVerticalOffset(true) + |
622 kTabstripTopShadowThickness); | 588 kTabstripTopShadowThickness); |
623 frame_background_->set_theme_background_y(theme_background_y); | 589 frame_background_->set_theme_background_y(theme_background_y); |
624 | 590 |
625 frame_background_->PaintMaximized(canvas, this); | 591 frame_background_->PaintMaximized(canvas, this); |
626 | 592 |
627 // TODO(jamescook): Migrate this into FrameBackground. | 593 // TODO(jamescook): Migrate this into FrameBackground. |
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
920 // side of the caption buttons. In maximized mode we extend the rightmost | 886 // side of the caption buttons. In maximized mode we extend the rightmost |
921 // button to the screen corner to obey Fitts' Law. | 887 // button to the screen corner to obey Fitts' Law. |
922 int right_extra_width = is_maximized ? | 888 int right_extra_width = is_maximized ? |
923 (kFrameBorderThickness - kFrameShadowThickness) : 0; | 889 (kFrameBorderThickness - kFrameShadowThickness) : 0; |
924 gfx::Size close_button_size = close_button_->GetPreferredSize(); | 890 gfx::Size close_button_size = close_button_->GetPreferredSize(); |
925 close_button_->SetBounds(width() - FrameBorderThickness(false) - | 891 close_button_->SetBounds(width() - FrameBorderThickness(false) - |
926 right_extra_width - close_button_size.width(), caption_y, | 892 right_extra_width - close_button_size.width(), caption_y, |
927 close_button_size.width() + right_extra_width, | 893 close_button_size.width() + right_extra_width, |
928 close_button_size.height()); | 894 close_button_size.height()); |
929 | 895 |
930 // Both ChromeOS and Aura laptop mode use a single main window. | |
931 if (frame()->IsSingleWindowMode()) { | |
932 // LayoutWindowControls could be triggered from | |
933 // NativeWidgetGtk::UpdateWindowTitle(), which could happen when user | |
934 // navigates in fullscreen mode. And because | |
935 // BrowserFrameChromeos::IsMaximized() return false for fullscreen mode, we | |
936 // explicitly test fullscreen mode here and make it use the same code path | |
937 // as maximized mode. | |
938 // TODO(oshima): Optimize the relayout logic to defer the frame view's | |
939 // relayout until it is necessary, i.e when it becomes visible. | |
940 if (is_maximized || frame()->IsFullscreen()) { | |
941 minimize_button_->SetVisible(false); | |
942 restore_button_->SetVisible(false); | |
943 maximize_button_->SetVisible(false); | |
944 | |
945 if (browser_view()->browser()->is_devtools()) { | |
946 close_button_->SetVisible(true); | |
947 minimize_button_->SetBounds(close_button_->bounds().x(), 0, 0, 0); | |
948 } else { | |
949 close_button_->SetVisible(false); | |
950 // Set the bounds of the minimize button so that we don't have to change | |
951 // other places that rely on the bounds. Put it slightly to the right | |
952 // of the edge of the view, so that when we remove the spacing it lines | |
953 // up with the edge. | |
954 minimize_button_->SetBounds(width() - FrameBorderThickness(false) + | |
955 kNewTabCaptionMaximizedSpacing, 0, 0, 0); | |
956 } | |
957 return; | |
958 } | |
959 } | |
960 // Aura can transition in and out of single-window mode, so be sure the | |
961 // close button is visible after the change. | |
962 close_button_->SetVisible(true); | |
963 | |
964 // When the window is restored, we show a maximized button; otherwise, we show | 896 // When the window is restored, we show a maximized button; otherwise, we show |
965 // a restore button. | 897 // a restore button. |
966 bool is_restored = !is_maximized && !frame()->IsMinimized(); | 898 bool is_restored = !is_maximized && !frame()->IsMinimized(); |
967 views::ImageButton* invisible_button = is_restored ? | 899 views::ImageButton* invisible_button = is_restored ? |
968 restore_button_ : maximize_button_; | 900 restore_button_ : maximize_button_; |
969 invisible_button->SetVisible(false); | 901 invisible_button->SetVisible(false); |
970 | 902 |
971 views::ImageButton* visible_button = is_restored ? | 903 views::ImageButton* visible_button = is_restored ? |
972 maximize_button_ : restore_button_; | 904 maximize_button_ : restore_button_; |
973 visible_button->SetVisible(true); | 905 visible_button->SetVisible(true); |
974 visible_button->SetImageAlignment(views::ImageButton::ALIGN_LEFT, | 906 visible_button->SetImageAlignment(views::ImageButton::ALIGN_LEFT, |
975 views::ImageButton::ALIGN_BOTTOM); | 907 views::ImageButton::ALIGN_BOTTOM); |
976 gfx::Size visible_button_size = visible_button->GetPreferredSize(); | 908 gfx::Size visible_button_size = visible_button->GetPreferredSize(); |
977 visible_button->SetBounds(close_button_->x() - visible_button_size.width(), | 909 visible_button->SetBounds(close_button_->x() - visible_button_size.width(), |
978 caption_y, visible_button_size.width(), | 910 caption_y, visible_button_size.width(), |
979 visible_button_size.height()); | 911 visible_button_size.height()); |
980 | 912 |
981 #if defined(USE_AURA) | |
982 // TODO(jamescook): Go back to showing minimize button when Aura uses its | |
983 // own custom window frame, BrowserNonClientFrameViewAura. | |
984 minimize_button_->SetVisible(false); | |
985 #else | |
986 minimize_button_->SetVisible(true); | 913 minimize_button_->SetVisible(true); |
987 #endif | |
988 minimize_button_->SetImageAlignment(views::ImageButton::ALIGN_LEFT, | 914 minimize_button_->SetImageAlignment(views::ImageButton::ALIGN_LEFT, |
989 views::ImageButton::ALIGN_BOTTOM); | 915 views::ImageButton::ALIGN_BOTTOM); |
990 gfx::Size minimize_button_size = minimize_button_->GetPreferredSize(); | 916 gfx::Size minimize_button_size = minimize_button_->GetPreferredSize(); |
991 minimize_button_->SetBounds( | 917 minimize_button_->SetBounds( |
992 visible_button->x() - minimize_button_size.width(), caption_y, | 918 visible_button->x() - minimize_button_size.width(), caption_y, |
993 minimize_button_size.width(), | 919 minimize_button_size.width(), |
994 minimize_button_size.height()); | 920 minimize_button_size.height()); |
995 } | 921 } |
996 | 922 |
997 void OpaqueBrowserFrameView::LayoutTitleBar() { | 923 void OpaqueBrowserFrameView::LayoutTitleBar() { |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1041 | 967 |
1042 gfx::Rect OpaqueBrowserFrameView::CalculateClientAreaBounds(int width, | 968 gfx::Rect OpaqueBrowserFrameView::CalculateClientAreaBounds(int width, |
1043 int height) const { | 969 int height) const { |
1044 int top_height = NonClientTopBorderHeight(false); | 970 int top_height = NonClientTopBorderHeight(false); |
1045 int border_thickness = NonClientBorderThickness(); | 971 int border_thickness = NonClientBorderThickness(); |
1046 return gfx::Rect(border_thickness, top_height, | 972 return gfx::Rect(border_thickness, top_height, |
1047 std::max(0, width - (2 * border_thickness)), | 973 std::max(0, width - (2 * border_thickness)), |
1048 std::max(0, height - GetReservedHeight() - | 974 std::max(0, height - GetReservedHeight() - |
1049 top_height - border_thickness)); | 975 top_height - border_thickness)); |
1050 } | 976 } |
OLD | NEW |