| 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/base/l10n/l10n_util.h" | 35 #include "ui/base/l10n/l10n_util.h" |
| 36 #include "ui/base/resource/resource_bundle.h" | 36 #include "ui/base/resource/resource_bundle.h" |
| 37 #include "ui/base/theme_provider.h" | 37 #include "ui/base/theme_provider.h" |
| 38 #include "ui/gfx/canvas.h" | 38 #include "ui/gfx/canvas.h" |
| 39 #include "ui/gfx/font.h" | 39 #include "ui/gfx/font.h" |
| 40 #include "ui/gfx/image/image.h" | 40 #include "ui/gfx/image/image.h" |
| 41 #include "ui/gfx/image/image_skia.h" | 41 #include "ui/gfx/image/image_skia.h" |
| 42 #include "ui/gfx/path.h" | 42 #include "ui/gfx/path.h" |
| 43 #include "ui/views/controls/button/image_button.h" | 43 #include "ui/views/controls/button/image_button.h" |
| 44 #include "ui/views/controls/image_view.h" | 44 #include "ui/views/controls/image_view.h" |
| 45 #include "ui/views/controls/label.h" |
| 45 #include "ui/views/widget/root_view.h" | 46 #include "ui/views/widget/root_view.h" |
| 46 #include "ui/views/window/frame_background.h" | 47 #include "ui/views/window/frame_background.h" |
| 47 #include "ui/views/window/window_shape.h" | 48 #include "ui/views/window/window_shape.h" |
| 48 | 49 |
| 49 #if defined(OS_WIN) | 50 #if defined(OS_WIN) |
| 50 #include "base/win/metro.h" | 51 #include "base/win/metro.h" |
| 51 #endif // OS_WIN | 52 #endif // OS_WIN |
| 52 | 53 |
| 53 using content::WebContents; | 54 using content::WebContents; |
| 54 | 55 |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 132 // OpaqueBrowserFrameView, public: | 133 // OpaqueBrowserFrameView, public: |
| 133 | 134 |
| 134 OpaqueBrowserFrameView::OpaqueBrowserFrameView(BrowserFrame* frame, | 135 OpaqueBrowserFrameView::OpaqueBrowserFrameView(BrowserFrame* frame, |
| 135 BrowserView* browser_view) | 136 BrowserView* browser_view) |
| 136 : BrowserNonClientFrameView(frame, browser_view), | 137 : BrowserNonClientFrameView(frame, browser_view), |
| 137 minimize_button_(NULL), | 138 minimize_button_(NULL), |
| 138 maximize_button_(NULL), | 139 maximize_button_(NULL), |
| 139 restore_button_(NULL), | 140 restore_button_(NULL), |
| 140 close_button_(NULL), | 141 close_button_(NULL), |
| 141 window_icon_(NULL), | 142 window_icon_(NULL), |
| 143 window_title_(NULL), |
| 142 frame_background_(new views::FrameBackground()) { | 144 frame_background_(new views::FrameBackground()) { |
| 143 if (ShouldAddDefaultCaptionButtons()) { | 145 if (ShouldAddDefaultCaptionButtons()) { |
| 144 minimize_button_ = InitWindowCaptionButton(IDR_MINIMIZE, | 146 minimize_button_ = InitWindowCaptionButton(IDR_MINIMIZE, |
| 145 IDR_MINIMIZE_H, | 147 IDR_MINIMIZE_H, |
| 146 IDR_MINIMIZE_P, | 148 IDR_MINIMIZE_P, |
| 147 IDR_MINIMIZE_BUTTON_MASK, | 149 IDR_MINIMIZE_BUTTON_MASK, |
| 148 IDS_ACCNAME_MINIMIZE); | 150 IDS_ACCNAME_MINIMIZE); |
| 149 maximize_button_ = InitWindowCaptionButton(IDR_MAXIMIZE, | 151 maximize_button_ = InitWindowCaptionButton(IDR_MAXIMIZE, |
| 150 IDR_MAXIMIZE_H, | 152 IDR_MAXIMIZE_H, |
| 151 IDR_MAXIMIZE_P, | 153 IDR_MAXIMIZE_P, |
| (...skipping 12 matching lines...) Expand all Loading... |
| 164 } | 166 } |
| 165 | 167 |
| 166 // Initializing the TabIconView is expensive, so only do it if we need to. | 168 // Initializing the TabIconView is expensive, so only do it if we need to. |
| 167 if (browser_view->ShouldShowWindowIcon()) { | 169 if (browser_view->ShouldShowWindowIcon()) { |
| 168 window_icon_ = new TabIconView(this); | 170 window_icon_ = new TabIconView(this); |
| 169 window_icon_->set_is_light(true); | 171 window_icon_->set_is_light(true); |
| 170 AddChildView(window_icon_); | 172 AddChildView(window_icon_); |
| 171 window_icon_->Update(); | 173 window_icon_->Update(); |
| 172 } | 174 } |
| 173 | 175 |
| 176 window_title_ = new views::Label(browser_view->GetWindowTitle(), |
| 177 BrowserFrame::GetTitleFont()); |
| 178 window_title_->SetVisible(browser_view->ShouldShowWindowTitle()); |
| 179 window_title_->SetEnabledColor(SK_ColorWHITE); |
| 180 // TODO(msw): Use a transparent background color as a workaround to use the |
| 181 // gfx::Canvas::NO_SUBPIXEL_RENDERING flag and avoid some visual artifacts. |
| 182 window_title_->SetBackgroundColor(0x00000000); |
| 183 window_title_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); |
| 184 window_title_->SetElideBehavior(views::Label::ELIDE_AT_END); |
| 185 AddChildView(window_title_); |
| 186 |
| 174 UpdateAvatarInfo(); | 187 UpdateAvatarInfo(); |
| 175 if (!browser_view->IsOffTheRecord()) { | 188 if (!browser_view->IsOffTheRecord()) { |
| 176 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED, | 189 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_CACHED_INFO_CHANGED, |
| 177 content::NotificationService::AllSources()); | 190 content::NotificationService::AllSources()); |
| 178 } | 191 } |
| 179 } | 192 } |
| 180 | 193 |
| 181 OpaqueBrowserFrameView::~OpaqueBrowserFrameView() { | 194 OpaqueBrowserFrameView::~OpaqueBrowserFrameView() { |
| 182 } | 195 } |
| 183 | 196 |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 381 // OpaqueBrowserFrameView, views::View overrides: | 394 // OpaqueBrowserFrameView, views::View overrides: |
| 382 | 395 |
| 383 void OpaqueBrowserFrameView::OnPaint(gfx::Canvas* canvas) { | 396 void OpaqueBrowserFrameView::OnPaint(gfx::Canvas* canvas) { |
| 384 if (frame()->IsFullscreen()) | 397 if (frame()->IsFullscreen()) |
| 385 return; // Nothing is visible, so don't bother to paint. | 398 return; // Nothing is visible, so don't bother to paint. |
| 386 | 399 |
| 387 if (frame()->IsMaximized()) | 400 if (frame()->IsMaximized()) |
| 388 PaintMaximizedFrameBorder(canvas); | 401 PaintMaximizedFrameBorder(canvas); |
| 389 else | 402 else |
| 390 PaintRestoredFrameBorder(canvas); | 403 PaintRestoredFrameBorder(canvas); |
| 391 PaintTitleBar(canvas); | 404 |
| 405 // The window icon and title are painted by their respective views. |
| 406 /* TODO(pkasting): If this window is active, we should also draw a drop |
| 407 * shadow on the title. This is tricky, because we don't want to hardcode a |
| 408 * shadow color (since we want to work with various themes), but we can't |
| 409 * alpha-blend either (since the Windows text APIs don't really do this). |
| 410 * So we'd need to sample the background color at the right location and |
| 411 * synthesize a good shadow color. */ |
| 412 |
| 392 if (browser_view()->IsToolbarVisible()) | 413 if (browser_view()->IsToolbarVisible()) |
| 393 PaintToolbarBackground(canvas); | 414 PaintToolbarBackground(canvas); |
| 394 if (!frame()->IsMaximized()) | 415 if (!frame()->IsMaximized()) |
| 395 PaintRestoredClientEdge(canvas); | 416 PaintRestoredClientEdge(canvas); |
| 396 } | 417 } |
| 397 | 418 |
| 398 void OpaqueBrowserFrameView::Layout() { | 419 void OpaqueBrowserFrameView::Layout() { |
| 399 LayoutWindowControls(); | 420 LayoutWindowControls(); |
| 400 LayoutTitleBar(); | 421 LayoutTitleBar(); |
| 401 LayoutAvatar(); | 422 LayoutAvatar(); |
| (...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 652 // edge. The graphic we use for this has a built in client edge, so we clip | 673 // edge. The graphic we use for this has a built in client edge, so we clip |
| 653 // it off the bottom. | 674 // it off the bottom. |
| 654 gfx::ImageSkia* top_center = | 675 gfx::ImageSkia* top_center = |
| 655 GetThemeProvider()->GetImageSkiaNamed(IDR_APP_TOP_CENTER); | 676 GetThemeProvider()->GetImageSkiaNamed(IDR_APP_TOP_CENTER); |
| 656 int edge_height = top_center->height() - kClientEdgeThickness; | 677 int edge_height = top_center->height() - kClientEdgeThickness; |
| 657 canvas->TileImageInt(*top_center, 0, | 678 canvas->TileImageInt(*top_center, 0, |
| 658 frame()->client_view()->y() - edge_height, width(), edge_height); | 679 frame()->client_view()->y() - edge_height, width(), edge_height); |
| 659 } | 680 } |
| 660 } | 681 } |
| 661 | 682 |
| 662 void OpaqueBrowserFrameView::PaintTitleBar(gfx::Canvas* canvas) { | |
| 663 // The window icon is painted by the TabIconView. | |
| 664 views::WidgetDelegate* delegate = frame()->widget_delegate(); | |
| 665 if (!delegate) { | |
| 666 LOG(WARNING) << "delegate is NULL"; | |
| 667 return; | |
| 668 } | |
| 669 if (delegate->ShouldShowWindowTitle()) { | |
| 670 canvas->DrawStringInt(delegate->GetWindowTitle(), | |
| 671 BrowserFrame::GetTitleFont(), | |
| 672 SK_ColorWHITE, GetMirroredXForRect(title_bounds_), | |
| 673 title_bounds_.y(), title_bounds_.width(), title_bounds_.height()); | |
| 674 /* TODO(pkasting): If this window is active, we should also draw a drop | |
| 675 * shadow on the title. This is tricky, because we don't want to hardcode a | |
| 676 * shadow color (since we want to work with various themes), but we can't | |
| 677 * alpha-blend either (since the Windows text APIs don't really do this). | |
| 678 * So we'd need to sample the background color at the right location and | |
| 679 * synthesize a good shadow color. */ | |
| 680 } | |
| 681 } | |
| 682 | |
| 683 void OpaqueBrowserFrameView::PaintToolbarBackground(gfx::Canvas* canvas) { | 683 void OpaqueBrowserFrameView::PaintToolbarBackground(gfx::Canvas* canvas) { |
| 684 gfx::Rect toolbar_bounds(browser_view()->GetToolbarBounds()); | 684 gfx::Rect toolbar_bounds(browser_view()->GetToolbarBounds()); |
| 685 if (toolbar_bounds.IsEmpty()) | 685 if (toolbar_bounds.IsEmpty()) |
| 686 return; | 686 return; |
| 687 gfx::Point toolbar_origin(toolbar_bounds.origin()); | 687 gfx::Point toolbar_origin(toolbar_bounds.origin()); |
| 688 ConvertPointToTarget(browser_view(), this, &toolbar_origin); | 688 ConvertPointToTarget(browser_view(), this, &toolbar_origin); |
| 689 toolbar_bounds.set_origin(toolbar_origin); | 689 toolbar_bounds.set_origin(toolbar_origin); |
| 690 | 690 |
| 691 int x = toolbar_bounds.x(); | 691 int x = toolbar_bounds.x(); |
| 692 int w = toolbar_bounds.width(); | 692 int w = toolbar_bounds.width(); |
| (...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 994 minimize_button_->SetImageAlignment(views::ImageButton::ALIGN_LEFT, | 994 minimize_button_->SetImageAlignment(views::ImageButton::ALIGN_LEFT, |
| 995 views::ImageButton::ALIGN_BOTTOM); | 995 views::ImageButton::ALIGN_BOTTOM); |
| 996 gfx::Size minimize_button_size = minimize_button_->GetPreferredSize(); | 996 gfx::Size minimize_button_size = minimize_button_->GetPreferredSize(); |
| 997 minimize_button_->SetBounds( | 997 minimize_button_->SetBounds( |
| 998 visible_button->x() - minimize_button_size.width(), caption_y, | 998 visible_button->x() - minimize_button_size.width(), caption_y, |
| 999 minimize_button_size.width(), | 999 minimize_button_size.width(), |
| 1000 minimize_button_size.height()); | 1000 minimize_button_size.height()); |
| 1001 } | 1001 } |
| 1002 | 1002 |
| 1003 void OpaqueBrowserFrameView::LayoutTitleBar() { | 1003 void OpaqueBrowserFrameView::LayoutTitleBar() { |
| 1004 // The window title is based on the calculated icon position, even when there | 1004 const views::WidgetDelegate* delegate = frame()->widget_delegate(); |
| 1005 // is no icon. | 1005 if (delegate) { |
| 1006 gfx::Rect icon_bounds(IconBounds()); | 1006 gfx::Rect icon_bounds(IconBounds()); |
| 1007 views::WidgetDelegate* delegate = frame()->widget_delegate(); | 1007 if (delegate->ShouldShowWindowIcon()) |
| 1008 if (delegate && delegate->ShouldShowWindowIcon()) | 1008 window_icon_->SetBoundsRect(icon_bounds); |
| 1009 window_icon_->SetBoundsRect(icon_bounds); | |
| 1010 | 1009 |
| 1011 // Size the title, if visible. | 1010 window_title_->SetVisible(delegate->ShouldShowWindowTitle()); |
| 1012 if (delegate && delegate->ShouldShowWindowTitle()) { | 1011 window_title_->SetText(delegate->GetWindowTitle()); |
| 1013 int title_x = delegate->ShouldShowWindowIcon() ? | 1012 const int title_x = delegate->ShouldShowWindowIcon() ? |
| 1014 icon_bounds.right() + kIconTitleSpacing : icon_bounds.x(); | 1013 icon_bounds.right() + kIconTitleSpacing : icon_bounds.x(); |
| 1015 int title_height = BrowserFrame::GetTitleFont().GetHeight(); | 1014 window_title_->SetBounds(title_x, icon_bounds.y(), |
| 1016 // We bias the title position so that when the difference between the icon | |
| 1017 // and title heights is odd, the extra pixel of the title is above the | |
| 1018 // vertical midline rather than below. This compensates for how the icon is | |
| 1019 // already biased downwards (see IconBounds()) and helps prevent descenders | |
| 1020 // on the title from overlapping the 3D edge at the bottom of the titlebar. | |
| 1021 title_bounds_.SetRect(title_x, | |
| 1022 icon_bounds.y() + ((icon_bounds.height() - title_height - 1) / 2), | |
| 1023 std::max(0, minimize_button_->x() - kTitleLogoSpacing - title_x), | 1015 std::max(0, minimize_button_->x() - kTitleLogoSpacing - title_x), |
| 1024 title_height); | 1016 icon_bounds.height()); |
| 1025 } | 1017 } |
| 1026 } | 1018 } |
| 1027 | 1019 |
| 1028 void OpaqueBrowserFrameView::LayoutAvatar() { | 1020 void OpaqueBrowserFrameView::LayoutAvatar() { |
| 1029 // Even though the avatar is used for both incognito and profiles we always | 1021 // Even though the avatar is used for both incognito and profiles we always |
| 1030 // use the incognito icon to layout the avatar button. The profile icon | 1022 // use the incognito icon to layout the avatar button. The profile icon |
| 1031 // can be customized so we can't depend on its size to perform layout. | 1023 // can be customized so we can't depend on its size to perform layout. |
| 1032 gfx::ImageSkia incognito_icon = browser_view()->GetOTRAvatarIcon(); | 1024 gfx::ImageSkia incognito_icon = browser_view()->GetOTRAvatarIcon(); |
| 1033 | 1025 |
| 1034 int avatar_bottom = GetTabStripInsets(false).top + | 1026 int avatar_bottom = GetTabStripInsets(false).top + |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1047 | 1039 |
| 1048 gfx::Rect OpaqueBrowserFrameView::CalculateClientAreaBounds(int width, | 1040 gfx::Rect OpaqueBrowserFrameView::CalculateClientAreaBounds(int width, |
| 1049 int height) const { | 1041 int height) const { |
| 1050 int top_height = NonClientTopBorderHeight(false); | 1042 int top_height = NonClientTopBorderHeight(false); |
| 1051 int border_thickness = NonClientBorderThickness(); | 1043 int border_thickness = NonClientBorderThickness(); |
| 1052 return gfx::Rect(border_thickness, top_height, | 1044 return gfx::Rect(border_thickness, top_height, |
| 1053 std::max(0, width - (2 * border_thickness)), | 1045 std::max(0, width - (2 * border_thickness)), |
| 1054 std::max(0, height - GetReservedHeight() - | 1046 std::max(0, height - GetReservedHeight() - |
| 1055 top_height - border_thickness)); | 1047 top_height - border_thickness)); |
| 1056 } | 1048 } |
| OLD | NEW |