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/ash/browser_non_client_frame_view_ash.h" | 5 #include "chrome/browser/ui/views/ash/browser_non_client_frame_view_ash.h" |
6 | 6 |
7 #include "ash/wm/frame_painter.h" | 7 #include "ash/wm/frame_painter.h" |
8 #include "ash/wm/workspace/frame_maximize_button.h" | 8 #include "ash/wm/workspace/frame_maximize_button.h" |
9 #include "chrome/browser/themes/theme_service.h" | 9 #include "chrome/browser/themes/theme_service.h" |
| 10 #include "chrome/browser/ui/browser.h" |
| 11 #include "chrome/browser/ui/search/search.h" |
| 12 #include "chrome/browser/ui/search/search_delegate.h" |
| 13 #include "chrome/browser/ui/search/search_model.h" |
10 #include "chrome/browser/ui/views/avatar_menu_button.h" | 14 #include "chrome/browser/ui/views/avatar_menu_button.h" |
11 #include "chrome/browser/ui/views/frame/browser_frame.h" | 15 #include "chrome/browser/ui/views/frame/browser_frame.h" |
12 #include "chrome/browser/ui/views/frame/browser_view.h" | 16 #include "chrome/browser/ui/views/frame/browser_view.h" |
13 #include "chrome/browser/ui/views/tabs/tab_strip.h" | 17 #include "chrome/browser/ui/views/tabs/tab_strip.h" |
| 18 #include "chrome/browser/ui/views/toolbar_view.h" |
14 #include "content/public/browser/web_contents.h" | 19 #include "content/public/browser/web_contents.h" |
15 #include "grit/generated_resources.h" // Accessibility names | 20 #include "grit/generated_resources.h" // Accessibility names |
16 #include "grit/theme_resources.h" | 21 #include "grit/theme_resources.h" |
17 #include "grit/theme_resources_standard.h" | 22 #include "grit/theme_resources_standard.h" |
18 #include "grit/ui_resources.h" | 23 #include "grit/ui_resources.h" |
19 #include "ui/aura/client/aura_constants.h" | 24 #include "ui/aura/client/aura_constants.h" |
20 #include "ui/aura/window.h" | 25 #include "ui/aura/window.h" |
21 #include "ui/base/accessibility/accessible_view_state.h" | 26 #include "ui/base/accessibility/accessible_view_state.h" |
22 #include "ui/base/hit_test.h" | 27 #include "ui/base/hit_test.h" |
23 #include "ui/base/l10n/l10n_util.h" | 28 #include "ui/base/l10n/l10n_util.h" |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
123 BrowserFrame* frame, BrowserView* browser_view) | 128 BrowserFrame* frame, BrowserView* browser_view) |
124 : BrowserNonClientFrameView(frame, browser_view), | 129 : BrowserNonClientFrameView(frame, browser_view), |
125 size_button_(NULL), | 130 size_button_(NULL), |
126 close_button_(NULL), | 131 close_button_(NULL), |
127 window_icon_(NULL), | 132 window_icon_(NULL), |
128 frame_painter_(new ash::FramePainter), | 133 frame_painter_(new ash::FramePainter), |
129 size_button_minimizes_(false) { | 134 size_button_minimizes_(false) { |
130 } | 135 } |
131 | 136 |
132 BrowserNonClientFrameViewAsh::~BrowserNonClientFrameViewAsh() { | 137 BrowserNonClientFrameViewAsh::~BrowserNonClientFrameViewAsh() { |
| 138 // A non-NULL |size_button_| means it was initialized in Init() where |
| 139 // |this| was added as observer to ToolbarSearchAnimator, so remove it now. |
| 140 if (size_button_) { |
| 141 browser_view()->browser()->search_delegate()->toolbar_search_animator(). |
| 142 RemoveObserver(this); |
| 143 } |
133 } | 144 } |
134 | 145 |
135 void BrowserNonClientFrameViewAsh::Init() { | 146 void BrowserNonClientFrameViewAsh::Init() { |
136 // Panels only minimize. | 147 // Panels only minimize. |
137 ash::FramePainter::SizeButtonBehavior size_button_behavior; | 148 ash::FramePainter::SizeButtonBehavior size_button_behavior; |
138 if (browser_view()->browser()->is_type_panel() && | 149 if (browser_view()->browser()->is_type_panel() && |
139 browser_view()->browser()->app_type() == Browser::APP_TYPE_CHILD) { | 150 browser_view()->browser()->app_type() == Browser::APP_TYPE_CHILD) { |
140 size_button_minimizes_ = true; | 151 size_button_minimizes_ = true; |
141 size_button_ = new views::ImageButton(this); | 152 size_button_ = new views::ImageButton(this); |
142 size_button_behavior = ash::FramePainter::SIZE_BUTTON_MINIMIZES; | 153 size_button_behavior = ash::FramePainter::SIZE_BUTTON_MINIMIZES; |
(...skipping 16 matching lines...) Expand all Loading... |
159 AddChildView(window_icon_); | 170 AddChildView(window_icon_); |
160 window_icon_->Update(); | 171 window_icon_->Update(); |
161 } | 172 } |
162 | 173 |
163 // Create incognito icon if necessary. | 174 // Create incognito icon if necessary. |
164 UpdateAvatarInfo(); | 175 UpdateAvatarInfo(); |
165 | 176 |
166 // Frame painter handles layout of these buttons. | 177 // Frame painter handles layout of these buttons. |
167 frame_painter_->Init(frame(), window_icon_, size_button_, close_button_, | 178 frame_painter_->Init(frame(), window_icon_, size_button_, close_button_, |
168 size_button_behavior); | 179 size_button_behavior); |
| 180 |
| 181 browser_view()->browser()->search_delegate()->toolbar_search_animator(). |
| 182 AddObserver(this); |
169 } | 183 } |
170 | 184 |
171 /////////////////////////////////////////////////////////////////////////////// | 185 /////////////////////////////////////////////////////////////////////////////// |
172 // BrowserNonClientFrameView overrides: | 186 // BrowserNonClientFrameView overrides: |
173 | 187 |
174 gfx::Rect BrowserNonClientFrameViewAsh::GetBoundsForTabStrip( | 188 gfx::Rect BrowserNonClientFrameViewAsh::GetBoundsForTabStrip( |
175 views::View* tabstrip) const { | 189 views::View* tabstrip) const { |
176 if (!tabstrip) | 190 if (!tabstrip) |
177 return gfx::Rect(); | 191 return gfx::Rect(); |
178 int tabstrip_x = | 192 int tabstrip_x = |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
253 // theme, so we look it up for each paint. | 267 // theme, so we look it up for each paint. |
254 frame_painter_->PaintHeader( | 268 frame_painter_->PaintHeader( |
255 this, | 269 this, |
256 canvas, | 270 canvas, |
257 ShouldPaintAsActive() ? | 271 ShouldPaintAsActive() ? |
258 ash::FramePainter::ACTIVE : ash::FramePainter::INACTIVE, | 272 ash::FramePainter::ACTIVE : ash::FramePainter::INACTIVE, |
259 GetThemeFrameImageId(), | 273 GetThemeFrameImageId(), |
260 GetThemeFrameOverlayImage()); | 274 GetThemeFrameOverlayImage()); |
261 if (browser_view()->ShouldShowWindowTitle()) | 275 if (browser_view()->ShouldShowWindowTitle()) |
262 frame_painter_->PaintTitleBar(this, canvas, BrowserFrame::GetTitleFont()); | 276 frame_painter_->PaintTitleBar(this, canvas, BrowserFrame::GetTitleFont()); |
263 if (browser_view()->IsToolbarVisible()) | 277 if (browser_view()->IsToolbarVisible()) { |
264 PaintToolbarBackground(canvas); | 278 chrome::search::Mode mode = |
265 else | 279 browser_view()->browser()->search_model()->mode(); |
| 280 bool fading_in = false; |
| 281 // For |MODE_SEARCH|, get current state of background animation to figure |
| 282 // out if we're waiting to fade in or in the process of fading in new |
| 283 // background for |MODE_SEARCH|. |
| 284 // In the former case, just paint the previous background for |MODE_NTP|. |
| 285 // In the latter case, paint the previous background for |MODE_NTP| and then |
| 286 // the new background at specified opacity value. |
| 287 if (mode.is_search()) { |
| 288 chrome::search::ToolbarSearchAnimator::BackgroundState background_state = |
| 289 chrome::search::ToolbarSearchAnimator::BACKGROUND_STATE_DEFAULT; |
| 290 double search_background_opacity = -1.0f; |
| 291 browser_view()->browser()->search_delegate()->toolbar_search_animator(). |
| 292 GetCurrentBackgroundState(&background_state, |
| 293 &search_background_opacity); |
| 294 if (background_state & |
| 295 chrome::search::ToolbarSearchAnimator::BACKGROUND_STATE_NTP) { |
| 296 // Paint background for |MODE_NTP|. |
| 297 PaintToolbarBackground(canvas, chrome::search::Mode::MODE_NTP); |
| 298 // We're done if we're not showing background for SEARCH mode. |
| 299 if (!(background_state & chrome::search::ToolbarSearchAnimator:: |
| 300 BACKGROUND_STATE_SEARCH)) { |
| 301 return; |
| 302 } |
| 303 // Otherwise, we're fading in the new background at |
| 304 // |search_background_opacity|. |
| 305 fading_in = true; |
| 306 canvas->SaveLayerAlpha(static_cast<uint8>( |
| 307 search_background_opacity * 0xFF)); |
| 308 } |
| 309 } |
| 310 // Paint the background for the current mode. |
| 311 PaintToolbarBackground(canvas, mode.mode); |
| 312 // If we're fading in and have saved canvas, restore it now. |
| 313 if (fading_in) |
| 314 canvas->Restore(); |
| 315 } else { |
266 PaintContentEdge(canvas); | 316 PaintContentEdge(canvas); |
| 317 } |
267 } | 318 } |
268 | 319 |
269 void BrowserNonClientFrameViewAsh::Layout() { | 320 void BrowserNonClientFrameViewAsh::Layout() { |
270 bool maximized_layout = UseShortHeader(); | 321 bool maximized_layout = UseShortHeader(); |
271 frame_painter_->LayoutHeader(this, maximized_layout); | 322 frame_painter_->LayoutHeader(this, maximized_layout); |
272 if (avatar_button()) | 323 if (avatar_button()) |
273 LayoutAvatar(); | 324 LayoutAvatar(); |
274 BrowserNonClientFrameView::Layout(); | 325 BrowserNonClientFrameView::Layout(); |
275 } | 326 } |
276 | 327 |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
342 } | 393 } |
343 | 394 |
344 gfx::ImageSkia BrowserNonClientFrameViewAsh::GetFaviconForTabIconView() { | 395 gfx::ImageSkia BrowserNonClientFrameViewAsh::GetFaviconForTabIconView() { |
345 views::WidgetDelegate* delegate = frame()->widget_delegate(); | 396 views::WidgetDelegate* delegate = frame()->widget_delegate(); |
346 if (!delegate) | 397 if (!delegate) |
347 return gfx::ImageSkia(); | 398 return gfx::ImageSkia(); |
348 return delegate->GetWindowIcon(); | 399 return delegate->GetWindowIcon(); |
349 } | 400 } |
350 | 401 |
351 /////////////////////////////////////////////////////////////////////////////// | 402 /////////////////////////////////////////////////////////////////////////////// |
| 403 // chrome::search::ToolbarSearchAnimator::Observer overrides: |
| 404 |
| 405 void BrowserNonClientFrameViewAsh::OnToolbarBackgroundAnimatorProgressed() { |
| 406 // We're fading in the toolbar background, repaint the toolbar background. |
| 407 browser_view()->toolbar()->SchedulePaint(); |
| 408 } |
| 409 |
| 410 void BrowserNonClientFrameViewAsh::OnToolbarBackgroundAnimatorCanceled( |
| 411 TabContents* tab_contents) { |
| 412 // Fade in of toolbar background has been canceled, repaint the toolbar |
| 413 // background. |
| 414 browser_view()->toolbar()->SchedulePaint(); |
| 415 } |
| 416 |
| 417 /////////////////////////////////////////////////////////////////////////////// |
352 // BrowserNonClientFrameViewAsh, private: | 418 // BrowserNonClientFrameViewAsh, private: |
353 | 419 |
354 | 420 |
355 int BrowserNonClientFrameViewAsh::NonClientTopBorderHeight( | 421 int BrowserNonClientFrameViewAsh::NonClientTopBorderHeight( |
356 bool force_restored) const { | 422 bool force_restored) const { |
357 if (force_restored) | 423 if (force_restored) |
358 return tabstrip_top_spacing_tall(); | 424 return tabstrip_top_spacing_tall(); |
359 if (frame()->IsFullscreen()) | 425 if (frame()->IsFullscreen()) |
360 return 0; | 426 return 0; |
361 // Windows with tab strips need a smaller non-client area. | 427 // Windows with tab strips need a smaller non-client area. |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
404 NonClientTopBorderHeight(false) + kContentShadowHeight: | 470 NonClientTopBorderHeight(false) + kContentShadowHeight: |
405 avatar_restored_y; | 471 avatar_restored_y; |
406 gfx::Rect avatar_bounds(kAvatarSideSpacing, | 472 gfx::Rect avatar_bounds(kAvatarSideSpacing, |
407 avatar_y, | 473 avatar_y, |
408 incognito_icon.width(), | 474 incognito_icon.width(), |
409 avatar_bottom - avatar_y); | 475 avatar_bottom - avatar_y); |
410 avatar_button()->SetBoundsRect(avatar_bounds); | 476 avatar_button()->SetBoundsRect(avatar_bounds); |
411 } | 477 } |
412 | 478 |
413 void BrowserNonClientFrameViewAsh::PaintToolbarBackground( | 479 void BrowserNonClientFrameViewAsh::PaintToolbarBackground( |
414 gfx::Canvas* canvas) { | 480 gfx::Canvas* canvas, |
| 481 chrome::search::Mode::Type mode) { |
415 gfx::Rect toolbar_bounds(browser_view()->GetToolbarBounds()); | 482 gfx::Rect toolbar_bounds(browser_view()->GetToolbarBounds()); |
416 if (toolbar_bounds.IsEmpty()) | 483 if (toolbar_bounds.IsEmpty()) |
417 return; | 484 return; |
418 gfx::Point toolbar_origin(toolbar_bounds.origin()); | 485 gfx::Point toolbar_origin(toolbar_bounds.origin()); |
419 ConvertPointToView(browser_view(), this, &toolbar_origin); | 486 ConvertPointToView(browser_view(), this, &toolbar_origin); |
420 toolbar_bounds.set_origin(toolbar_origin); | 487 toolbar_bounds.set_origin(toolbar_origin); |
421 | 488 |
422 int x = toolbar_bounds.x(); | 489 int x = toolbar_bounds.x(); |
423 int w = toolbar_bounds.width(); | 490 int w = toolbar_bounds.width(); |
424 int y = toolbar_bounds.y(); | 491 int y = toolbar_bounds.y(); |
425 int h = toolbar_bounds.height(); | 492 int h = toolbar_bounds.height(); |
426 | 493 |
427 // Gross hack: We split the toolbar images into two pieces, since sometimes | 494 // Gross hack: We split the toolbar images into two pieces, since sometimes |
428 // (popup mode) the toolbar isn't tall enough to show the whole image. The | 495 // (popup mode) the toolbar isn't tall enough to show the whole image. The |
429 // split happens between the top shadow section and the bottom gradient | 496 // split happens between the top shadow section and the bottom gradient |
430 // section so that we never break the gradient. | 497 // section so that we never break the gradient. |
431 int split_point = kFrameShadowThickness * 2; | 498 int split_point = kFrameShadowThickness * 2; |
432 int bottom_y = y + split_point; | 499 int bottom_y = y + split_point; |
433 ui::ThemeProvider* tp = GetThemeProvider(); | 500 ui::ThemeProvider* tp = GetThemeProvider(); |
434 int bottom_edge_height = h - split_point; | 501 int bottom_edge_height = h - split_point; |
435 | 502 |
| 503 SkColor background_color = browser_view()->GetToolbarBackgroundColor(mode); |
436 canvas->FillRect(gfx::Rect(x, bottom_y, w, bottom_edge_height), | 504 canvas->FillRect(gfx::Rect(x, bottom_y, w, bottom_edge_height), |
437 tp->GetColor(ThemeService::COLOR_TOOLBAR)); | 505 background_color); |
438 | 506 |
439 // Paint the main toolbar image. Since this image is also used to draw the | 507 // Paint the main toolbar image. Since this image is also used to draw the |
440 // tab background, we must use the tab strip offset to compute the image | 508 // tab background, we must use the tab strip offset to compute the image |
441 // source y position. If you have to debug this code use an image editor | 509 // source y position. If you have to debug this code use an image editor |
442 // to paint a diagonal line through the toolbar image and ensure it lines up | 510 // to paint a diagonal line through the toolbar image and ensure it lines up |
443 // across the tab and toolbar. | 511 // across the tab and toolbar. |
444 gfx::ImageSkia* theme_toolbar = tp->GetImageSkiaNamed(IDR_THEME_TOOLBAR); | 512 gfx::ImageSkia* theme_toolbar = |
| 513 browser_view()->GetToolbarBackgroundImage(mode); |
445 canvas->TileImageInt( | 514 canvas->TileImageInt( |
446 *theme_toolbar, | 515 *theme_toolbar, |
447 x, bottom_y - GetHorizontalTabStripVerticalOffset(false), | 516 x, bottom_y - GetHorizontalTabStripVerticalOffset(false), |
448 x, bottom_y, | 517 x, bottom_y, |
449 w, theme_toolbar->height()); | 518 w, theme_toolbar->height()); |
450 | 519 |
451 // The content area line has a shadow that extends a couple of pixels above | 520 // The content area line has a shadow that extends a couple of pixels above |
452 // the toolbar bounds. | 521 // the toolbar bounds. |
453 const int kContentShadowHeight = 2; | 522 const int kContentShadowHeight = 2; |
454 gfx::ImageSkia* toolbar_top = | 523 gfx::ImageSkia* toolbar_top = |
(...skipping 11 matching lines...) Expand all Loading... |
466 y + kClientEdgeThickness + kContentShadowHeight, | 535 y + kClientEdgeThickness + kContentShadowHeight, |
467 toolbar_left->width(), theme_toolbar->height()); | 536 toolbar_left->width(), theme_toolbar->height()); |
468 gfx::ImageSkia* toolbar_right = | 537 gfx::ImageSkia* toolbar_right = |
469 tp->GetImageSkiaNamed(IDR_TOOLBAR_SHADE_RIGHT); | 538 tp->GetImageSkiaNamed(IDR_TOOLBAR_SHADE_RIGHT); |
470 canvas->TileImageInt(*toolbar_right, | 539 canvas->TileImageInt(*toolbar_right, |
471 0, 0, | 540 0, 0, |
472 w - toolbar_right->width() - 2 * kClientEdgeThickness, | 541 w - toolbar_right->width() - 2 * kClientEdgeThickness, |
473 y + kClientEdgeThickness + kContentShadowHeight, | 542 y + kClientEdgeThickness + kContentShadowHeight, |
474 toolbar_right->width(), theme_toolbar->height()); | 543 toolbar_right->width(), theme_toolbar->height()); |
475 | 544 |
476 // Draw the content/toolbar separator. | 545 // Only draw the content/toolbar separator if Instant Extended API is disabled |
477 canvas->FillRect(gfx::Rect(x + kClientEdgeThickness, | 546 // or mode is DEFAULT. |
478 toolbar_bounds.bottom() - kClientEdgeThickness, | 547 bool extended_instant_enabled = chrome::search::IsInstantExtendedAPIEnabled( |
479 w - (2 * kClientEdgeThickness), | 548 browser_view()->browser()->profile()); |
480 kClientEdgeThickness), | 549 if (!extended_instant_enabled || mode == chrome::search::Mode::MODE_DEFAULT) { |
481 ThemeService::GetDefaultColor(ThemeService::COLOR_TOOLBAR_SEPARATOR)); | 550 canvas->FillRect( |
| 551 gfx::Rect(x + kClientEdgeThickness, |
| 552 toolbar_bounds.bottom() - kClientEdgeThickness, |
| 553 w - (2 * kClientEdgeThickness), kClientEdgeThickness), |
| 554 ThemeService::GetDefaultColor(extended_instant_enabled ? |
| 555 ThemeService::COLOR_SEARCH_SEPARATOR_LINE : |
| 556 ThemeService::COLOR_TOOLBAR_SEPARATOR)); |
| 557 } |
482 } | 558 } |
483 | 559 |
484 void BrowserNonClientFrameViewAsh::PaintContentEdge(gfx::Canvas* canvas) { | 560 void BrowserNonClientFrameViewAsh::PaintContentEdge(gfx::Canvas* canvas) { |
485 canvas->FillRect(gfx::Rect(0, close_button_->bounds().bottom(), | 561 canvas->FillRect(gfx::Rect(0, close_button_->bounds().bottom(), |
486 width(), kClientEdgeThickness), | 562 width(), kClientEdgeThickness), |
487 ThemeService::GetDefaultColor(ThemeService::COLOR_TOOLBAR_SEPARATOR)); | 563 ThemeService::GetDefaultColor(ThemeService::COLOR_TOOLBAR_SEPARATOR)); |
488 } | 564 } |
489 | 565 |
490 int BrowserNonClientFrameViewAsh::GetThemeFrameImageId() const { | 566 int BrowserNonClientFrameViewAsh::GetThemeFrameImageId() const { |
491 bool is_incognito = browser_view()->IsOffTheRecord(); | 567 bool is_incognito = browser_view()->IsOffTheRecord(); |
(...skipping 21 matching lines...) Expand all Loading... |
513 BrowserNonClientFrameViewAsh::GetThemeFrameOverlayImage() const { | 589 BrowserNonClientFrameViewAsh::GetThemeFrameOverlayImage() const { |
514 ui::ThemeProvider* tp = GetThemeProvider(); | 590 ui::ThemeProvider* tp = GetThemeProvider(); |
515 if (tp->HasCustomImage(IDR_THEME_FRAME_OVERLAY) && | 591 if (tp->HasCustomImage(IDR_THEME_FRAME_OVERLAY) && |
516 browser_view()->IsBrowserTypeNormal() && | 592 browser_view()->IsBrowserTypeNormal() && |
517 !browser_view()->IsOffTheRecord()) { | 593 !browser_view()->IsOffTheRecord()) { |
518 return tp->GetImageSkiaNamed(ShouldPaintAsActive() ? | 594 return tp->GetImageSkiaNamed(ShouldPaintAsActive() ? |
519 IDR_THEME_FRAME_OVERLAY : IDR_THEME_FRAME_OVERLAY_INACTIVE); | 595 IDR_THEME_FRAME_OVERLAY : IDR_THEME_FRAME_OVERLAY_INACTIVE); |
520 } | 596 } |
521 return NULL; | 597 return NULL; |
522 } | 598 } |
OLD | NEW |