| 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 |