| OLD | NEW |
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 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/browser_non_client_frame_view_ash.h" | 5 #include "chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "ash/common/ash_layout_constants.h" | 9 #include "ash/common/ash_layout_constants.h" |
| 10 #include "ash/common/frame/caption_buttons/frame_caption_button_container_view.h
" | 10 #include "ash/common/frame/caption_buttons/frame_caption_button_container_view.h
" |
| 11 #include "ash/common/frame/default_header_painter.h" | 11 #include "ash/common/frame/default_header_painter.h" |
| 12 #include "ash/common/frame/frame_border_hit_test.h" | 12 #include "ash/common/frame/frame_border_hit_test.h" |
| 13 #include "ash/common/frame/header_painter_util.h" | 13 #include "ash/common/frame/header_painter_util.h" |
| 14 #include "ash/common/material_design/material_design_controller.h" | |
| 15 #include "ash/common/wm_lookup.h" | 14 #include "ash/common/wm_lookup.h" |
| 16 #include "ash/common/wm_shell.h" | 15 #include "ash/common/wm_shell.h" |
| 17 #include "ash/common/wm_window.h" | 16 #include "ash/common/wm_window.h" |
| 18 #include "build/build_config.h" | 17 #include "build/build_config.h" |
| 19 #include "chrome/browser/profiles/profiles_state.h" | 18 #include "chrome/browser/profiles/profiles_state.h" |
| 20 #include "chrome/browser/themes/theme_properties.h" | 19 #include "chrome/browser/themes/theme_properties.h" |
| 21 #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager.h" | 20 #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager.h" |
| 22 #include "chrome/browser/ui/browser.h" | 21 #include "chrome/browser/ui/browser.h" |
| 23 #include "chrome/browser/ui/layout_constants.h" | 22 #include "chrome/browser/ui/layout_constants.h" |
| 24 #include "chrome/browser/ui/views/frame/browser_frame.h" | 23 #include "chrome/browser/ui/views/frame/browser_frame.h" |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 119 } | 118 } |
| 120 | 119 |
| 121 /////////////////////////////////////////////////////////////////////////////// | 120 /////////////////////////////////////////////////////////////////////////////// |
| 122 // BrowserNonClientFrameView: | 121 // BrowserNonClientFrameView: |
| 123 | 122 |
| 124 gfx::Rect BrowserNonClientFrameViewAsh::GetBoundsForTabStrip( | 123 gfx::Rect BrowserNonClientFrameViewAsh::GetBoundsForTabStrip( |
| 125 views::View* tabstrip) const { | 124 views::View* tabstrip) const { |
| 126 if (!tabstrip) | 125 if (!tabstrip) |
| 127 return gfx::Rect(); | 126 return gfx::Rect(); |
| 128 | 127 |
| 129 // When the tab strip is painted in the immersive fullscreen light bar style, | |
| 130 // the caption buttons and the avatar button are not visible. However, their | |
| 131 // bounds are still used to compute the tab strip bounds so that the tabs have | |
| 132 // the same horizontal position when the tab strip is painted in the immersive | |
| 133 // light bar style as when the top-of-window views are revealed. | |
| 134 const int left_inset = GetTabStripLeftInset(); | 128 const int left_inset = GetTabStripLeftInset(); |
| 135 return gfx::Rect(left_inset, GetTopInset(false), | 129 return gfx::Rect(left_inset, GetTopInset(false), |
| 136 std::max(0, width() - left_inset - GetTabStripRightInset()), | 130 std::max(0, width() - left_inset - GetTabStripRightInset()), |
| 137 tabstrip->GetPreferredSize().height()); | 131 tabstrip->GetPreferredSize().height()); |
| 138 } | 132 } |
| 139 | 133 |
| 140 int BrowserNonClientFrameViewAsh::GetTopInset(bool restored) const { | 134 int BrowserNonClientFrameViewAsh::GetTopInset(bool restored) const { |
| 141 if (!ShouldPaint() || UseImmersiveLightbarHeaderStyle()) | 135 if (!ShouldPaint()) { |
| 136 // When immersive fullscreen unrevealed, tabstrip is offscreen with normal |
| 137 // tapstrip bounds, the top inset should reach this topmost edge. |
| 138 const ImmersiveModeController* const immersive_controller = |
| 139 browser_view()->immersive_mode_controller(); |
| 140 if (immersive_controller->IsEnabled() && |
| 141 !immersive_controller->IsRevealed()) { |
| 142 return (-1) * browser_view()->GetTabStripHeight(); |
| 143 } |
| 142 return 0; | 144 return 0; |
| 145 } |
| 143 | 146 |
| 144 if (!browser_view()->IsTabStripVisible()) { | 147 if (!browser_view()->IsTabStripVisible()) { |
| 145 return (UsePackagedAppHeaderStyle()) | 148 return (UsePackagedAppHeaderStyle()) |
| 146 ? header_painter_->GetHeaderHeight() | 149 ? header_painter_->GetHeaderHeight() |
| 147 : caption_button_container_->bounds().bottom(); | 150 : caption_button_container_->bounds().bottom(); |
| 148 } | 151 } |
| 149 | 152 |
| 150 const int header_height = restored | 153 const int header_height = restored |
| 151 ? GetAshLayoutSize( | 154 ? GetAshLayoutSize( |
| 152 AshLayoutSize::BROWSER_RESTORED_CAPTION_BUTTON).height() | 155 AshLayoutSize::BROWSER_RESTORED_CAPTION_BUTTON).height() |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 198 | 201 |
| 199 return hit_test; | 202 return hit_test; |
| 200 } | 203 } |
| 201 | 204 |
| 202 void BrowserNonClientFrameViewAsh::GetWindowMask(const gfx::Size& size, | 205 void BrowserNonClientFrameViewAsh::GetWindowMask(const gfx::Size& size, |
| 203 gfx::Path* window_mask) { | 206 gfx::Path* window_mask) { |
| 204 // Aura does not use window masks. | 207 // Aura does not use window masks. |
| 205 } | 208 } |
| 206 | 209 |
| 207 void BrowserNonClientFrameViewAsh::ResetWindowControls() { | 210 void BrowserNonClientFrameViewAsh::ResetWindowControls() { |
| 208 // Hide the caption buttons in immersive fullscreen when the tab light bar | 211 caption_button_container_->SetVisible(true); |
| 209 // is visible because it's confusing when the user hovers or clicks in the | |
| 210 // top-right of the screen and hits one. | |
| 211 // TODO(yiyix): Update |caption_button_container_|'s visibility calculation | |
| 212 // when Chrome OS MD is enabled by default. | |
| 213 caption_button_container_->SetVisible(!UseImmersiveLightbarHeaderStyle()); | |
| 214 caption_button_container_->ResetWindowControls(); | 212 caption_button_container_->ResetWindowControls(); |
| 215 } | 213 } |
| 216 | 214 |
| 217 void BrowserNonClientFrameViewAsh::UpdateWindowIcon() { | 215 void BrowserNonClientFrameViewAsh::UpdateWindowIcon() { |
| 218 if (window_icon_) | 216 if (window_icon_) |
| 219 window_icon_->SchedulePaint(); | 217 window_icon_->SchedulePaint(); |
| 220 } | 218 } |
| 221 | 219 |
| 222 void BrowserNonClientFrameViewAsh::UpdateWindowTitle() { | 220 void BrowserNonClientFrameViewAsh::UpdateWindowTitle() { |
| 223 if (!frame()->IsFullscreen()) | 221 if (!frame()->IsFullscreen()) |
| 224 header_painter_->SchedulePaintForTitle(); | 222 header_painter_->SchedulePaintForTitle(); |
| 225 } | 223 } |
| 226 | 224 |
| 227 void BrowserNonClientFrameViewAsh::SizeConstraintsChanged() { | 225 void BrowserNonClientFrameViewAsh::SizeConstraintsChanged() { |
| 228 } | 226 } |
| 229 | 227 |
| 230 /////////////////////////////////////////////////////////////////////////////// | 228 /////////////////////////////////////////////////////////////////////////////// |
| 231 // views::View: | 229 // views::View: |
| 232 | 230 |
| 233 void BrowserNonClientFrameViewAsh::OnPaint(gfx::Canvas* canvas) { | 231 void BrowserNonClientFrameViewAsh::OnPaint(gfx::Canvas* canvas) { |
| 234 if (!ShouldPaint()) | 232 if (!ShouldPaint()) |
| 235 return; | 233 return; |
| 236 | 234 |
| 237 if (UseImmersiveLightbarHeaderStyle()) { | |
| 238 // The light bar header is not themed because theming it does not look good. | |
| 239 canvas->FillRect( | |
| 240 gfx::Rect(width(), header_painter_->GetHeaderHeightForPainting()), | |
| 241 SK_ColorBLACK); | |
| 242 return; | |
| 243 } | |
| 244 | |
| 245 const bool should_paint_as_active = ShouldPaintAsActive(); | 235 const bool should_paint_as_active = ShouldPaintAsActive(); |
| 246 caption_button_container_->SetPaintAsActive(should_paint_as_active); | 236 caption_button_container_->SetPaintAsActive(should_paint_as_active); |
| 247 | 237 |
| 248 const ash::HeaderPainter::Mode header_mode = should_paint_as_active ? | 238 const ash::HeaderPainter::Mode header_mode = should_paint_as_active ? |
| 249 ash::HeaderPainter::MODE_ACTIVE : ash::HeaderPainter::MODE_INACTIVE; | 239 ash::HeaderPainter::MODE_ACTIVE : ash::HeaderPainter::MODE_INACTIVE; |
| 250 header_painter_->PaintHeader(canvas, header_mode); | 240 header_painter_->PaintHeader(canvas, header_mode); |
| 251 | 241 |
| 252 if (browser_view()->IsToolbarVisible() && | 242 if (browser_view()->IsToolbarVisible() && |
| 253 !browser_view()->toolbar()->GetPreferredSize().IsEmpty() && | 243 !browser_view()->toolbar()->GetPreferredSize().IsEmpty() && |
| 254 browser_view()->IsTabStripVisible()) { | 244 browser_view()->IsTabStripVisible()) { |
| 255 PaintToolbarBackground(canvas); | 245 PaintToolbarBackground(canvas); |
| 256 } | 246 } |
| 257 } | 247 } |
| 258 | 248 |
| 259 void BrowserNonClientFrameViewAsh::Layout() { | 249 void BrowserNonClientFrameViewAsh::Layout() { |
| 260 // The header must be laid out before computing |painted_height| because the | 250 // The header must be laid out before computing |painted_height| because the |
| 261 // computation of |painted_height| for app and popup windows depends on the | 251 // computation of |painted_height| for app and popup windows depends on the |
| 262 // position of the window controls. | 252 // position of the window controls. |
| 263 header_painter_->LayoutHeader(); | 253 header_painter_->LayoutHeader(); |
| 264 | 254 |
| 265 int painted_height = GetTopInset(false); | 255 int painted_height = GetTopInset(false); |
| 266 if (browser_view()->IsTabStripVisible()) { | 256 if (browser_view()->IsTabStripVisible()) |
| 267 const ImmersiveModeController* const immersive_controller = | 257 painted_height += browser_view()->tabstrip()->GetPreferredSize().height(); |
| 268 browser_view()->immersive_mode_controller(); | |
| 269 if (!immersive_controller->IsEnabled() || | |
| 270 immersive_controller->IsRevealed() || | |
| 271 !ash::MaterialDesignController::IsImmersiveModeMaterial()) { | |
| 272 painted_height += browser_view()->tabstrip()->GetPreferredSize().height(); | |
| 273 } | |
| 274 } | |
| 275 | 258 |
| 276 header_painter_->SetHeaderHeightForPainting(painted_height); | 259 header_painter_->SetHeaderHeightForPainting(painted_height); |
| 277 | 260 |
| 278 if (profile_indicator_icon()) | 261 if (profile_indicator_icon()) |
| 279 LayoutProfileIndicatorIcon(); | 262 LayoutProfileIndicatorIcon(); |
| 280 BrowserNonClientFrameView::Layout(); | 263 BrowserNonClientFrameView::Layout(); |
| 281 frame()->GetNativeWindow()->SetProperty( | 264 frame()->GetNativeWindow()->SetProperty( |
| 282 aura::client::kTopViewInset, | 265 aura::client::kTopViewInset, |
| 283 browser_view()->IsTabStripVisible() ? 0 : GetTopInset(true)); | 266 browser_view()->IsTabStripVisible() ? 0 : GetTopInset(true)); |
| 284 } | 267 } |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 384 ? (kAvatarIconPadding + GetIncognitoAvatarIcon().width()) | 367 ? (kAvatarIconPadding + GetIncognitoAvatarIcon().width()) |
| 385 : 0; | 368 : 0; |
| 386 return avatar_right + kAvatarIconPadding; | 369 return avatar_right + kAvatarIconPadding; |
| 387 } | 370 } |
| 388 | 371 |
| 389 int BrowserNonClientFrameViewAsh::GetTabStripRightInset() const { | 372 int BrowserNonClientFrameViewAsh::GetTabStripRightInset() const { |
| 390 return kTabstripRightSpacing + | 373 return kTabstripRightSpacing + |
| 391 caption_button_container_->GetPreferredSize().width(); | 374 caption_button_container_->GetPreferredSize().width(); |
| 392 } | 375 } |
| 393 | 376 |
| 394 bool BrowserNonClientFrameViewAsh::UseImmersiveLightbarHeaderStyle() const { | |
| 395 if (ash::MaterialDesignController::IsImmersiveModeMaterial()) | |
| 396 return false; | |
| 397 | |
| 398 const ImmersiveModeController* const immersive_controller = | |
| 399 browser_view()->immersive_mode_controller(); | |
| 400 return immersive_controller->IsEnabled() && | |
| 401 !immersive_controller->IsRevealed() && | |
| 402 browser_view()->IsTabStripVisible(); | |
| 403 } | |
| 404 | |
| 405 bool BrowserNonClientFrameViewAsh::UsePackagedAppHeaderStyle() const { | 377 bool BrowserNonClientFrameViewAsh::UsePackagedAppHeaderStyle() const { |
| 406 // Use for non tabbed trusted source windows, e.g. Settings, as well as apps. | 378 // Use for non tabbed trusted source windows, e.g. Settings, as well as apps. |
| 407 const Browser* const browser = browser_view()->browser(); | 379 const Browser* const browser = browser_view()->browser(); |
| 408 return (!browser->is_type_tabbed() && browser->is_trusted_source()) || | 380 return (!browser->is_type_tabbed() && browser->is_trusted_source()) || |
| 409 browser->is_app(); | 381 browser->is_app(); |
| 410 } | 382 } |
| 411 | 383 |
| 412 void BrowserNonClientFrameViewAsh::LayoutProfileIndicatorIcon() { | 384 void BrowserNonClientFrameViewAsh::LayoutProfileIndicatorIcon() { |
| 413 DCHECK(profile_indicator_icon()); | 385 DCHECK(profile_indicator_icon()); |
| 414 #if !defined(OS_CHROMEOS) | 386 #if !defined(OS_CHROMEOS) |
| 415 // ChromeOS shows avatar on V1 app. | 387 // ChromeOS shows avatar on V1 app. |
| 416 DCHECK(browser_view()->IsTabStripVisible()); | 388 DCHECK(browser_view()->IsTabStripVisible()); |
| 417 #endif | 389 #endif |
| 418 | 390 |
| 419 const gfx::ImageSkia incognito_icon = GetIncognitoAvatarIcon(); | 391 const gfx::ImageSkia incognito_icon = GetIncognitoAvatarIcon(); |
| 420 const int avatar_bottom = GetTopInset(false) + | 392 const int avatar_bottom = GetTopInset(false) + |
| 421 browser_view()->GetTabStripHeight() - | 393 browser_view()->GetTabStripHeight() - |
| 422 kAvatarIconPadding; | 394 kAvatarIconPadding; |
| 423 int avatar_y = avatar_bottom - incognito_icon.height(); | 395 int avatar_y = avatar_bottom - incognito_icon.height(); |
| 424 | 396 |
| 425 // Hide the incognito icon in immersive fullscreen when the tab light bar is | 397 const int avatar_height = avatar_bottom - avatar_y; |
| 426 // visible because the header is too short for the icognito icon to be | |
| 427 // recognizable. | |
| 428 const bool avatar_visible = !UseImmersiveLightbarHeaderStyle(); | |
| 429 const int avatar_height = avatar_visible ? (avatar_bottom - avatar_y) : 0; | |
| 430 profile_indicator_icon()->SetBounds(kAvatarIconPadding, avatar_y, | 398 profile_indicator_icon()->SetBounds(kAvatarIconPadding, avatar_y, |
| 431 incognito_icon.width(), avatar_height); | 399 incognito_icon.width(), avatar_height); |
| 432 profile_indicator_icon()->SetVisible(avatar_visible); | 400 profile_indicator_icon()->SetVisible(true); |
| 433 } | 401 } |
| 434 | 402 |
| 435 bool BrowserNonClientFrameViewAsh::ShouldPaint() const { | 403 bool BrowserNonClientFrameViewAsh::ShouldPaint() const { |
| 436 if (!frame()->IsFullscreen()) | 404 if (!frame()->IsFullscreen()) |
| 437 return true; | 405 return true; |
| 438 | 406 |
| 439 // We need to paint when in immersive fullscreen and either: | 407 // We need to paint when the top-of-window views are revealed in immersive |
| 440 // - The top-of-window views are revealed. | 408 // fullscreen. |
| 441 // - The lightbar style tabstrip is visible. | |
| 442 ImmersiveModeController* immersive_mode_controller = | 409 ImmersiveModeController* immersive_mode_controller = |
| 443 browser_view()->immersive_mode_controller(); | 410 browser_view()->immersive_mode_controller(); |
| 444 return immersive_mode_controller->IsEnabled() && | 411 return immersive_mode_controller->IsEnabled() && |
| 445 (immersive_mode_controller->IsRevealed() || | 412 immersive_mode_controller->IsRevealed(); |
| 446 UseImmersiveLightbarHeaderStyle()); | |
| 447 } | 413 } |
| 448 | 414 |
| 449 void BrowserNonClientFrameViewAsh::PaintToolbarBackground(gfx::Canvas* canvas) { | 415 void BrowserNonClientFrameViewAsh::PaintToolbarBackground(gfx::Canvas* canvas) { |
| 450 gfx::Rect toolbar_bounds(browser_view()->GetToolbarBounds()); | 416 gfx::Rect toolbar_bounds(browser_view()->GetToolbarBounds()); |
| 451 if (toolbar_bounds.IsEmpty()) | 417 if (toolbar_bounds.IsEmpty()) |
| 452 return; | 418 return; |
| 453 gfx::Point toolbar_origin(toolbar_bounds.origin()); | 419 gfx::Point toolbar_origin(toolbar_bounds.origin()); |
| 454 View::ConvertPointToTarget(browser_view(), this, &toolbar_origin); | 420 View::ConvertPointToTarget(browser_view(), this, &toolbar_origin); |
| 455 toolbar_bounds.set_origin(toolbar_origin); | 421 toolbar_bounds.set_origin(toolbar_origin); |
| 456 const ui::ThemeProvider* tp = GetThemeProvider(); | 422 const ui::ThemeProvider* tp = GetThemeProvider(); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 477 toolbar_bounds.width(), 0); | 443 toolbar_bounds.width(), 0); |
| 478 BrowserView::Paint1pxHorizontalLine(canvas, GetToolbarTopSeparatorColor(), | 444 BrowserView::Paint1pxHorizontalLine(canvas, GetToolbarTopSeparatorColor(), |
| 479 separator_rect, true); | 445 separator_rect, true); |
| 480 | 446 |
| 481 // Toolbar/content separator. | 447 // Toolbar/content separator. |
| 482 toolbar_bounds.Inset(kClientEdgeThickness, 0); | 448 toolbar_bounds.Inset(kClientEdgeThickness, 0); |
| 483 BrowserView::Paint1pxHorizontalLine( | 449 BrowserView::Paint1pxHorizontalLine( |
| 484 canvas, tp->GetColor(ThemeProperties::COLOR_TOOLBAR_BOTTOM_SEPARATOR), | 450 canvas, tp->GetColor(ThemeProperties::COLOR_TOOLBAR_BOTTOM_SEPARATOR), |
| 485 toolbar_bounds, true); | 451 toolbar_bounds, true); |
| 486 } | 452 } |
| OLD | NEW |