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 |