| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "ash/wm/header_painter.h" | 5 #include "ash/wm/header_painter.h" |
| 6 | 6 |
| 7 #include <vector> | 7 #include <vector> |
| 8 | 8 |
| 9 #include "ash/root_window_controller.h" | 9 #include "ash/root_window_controller.h" |
| 10 #include "ash/wm/caption_buttons/frame_caption_button_container_view.h" | 10 #include "ash/wm/caption_buttons/frame_caption_button_container_view.h" |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 133 namespace ash { | 133 namespace ash { |
| 134 | 134 |
| 135 /////////////////////////////////////////////////////////////////////////////// | 135 /////////////////////////////////////////////////////////////////////////////// |
| 136 // HeaderPainter, public: | 136 // HeaderPainter, public: |
| 137 | 137 |
| 138 HeaderPainter::HeaderPainter() | 138 HeaderPainter::HeaderPainter() |
| 139 : frame_(NULL), | 139 : frame_(NULL), |
| 140 header_view_(NULL), | 140 header_view_(NULL), |
| 141 window_icon_(NULL), | 141 window_icon_(NULL), |
| 142 caption_button_container_(NULL), | 142 caption_button_container_(NULL), |
| 143 window_(NULL), | |
| 144 header_height_(0), | 143 header_height_(0), |
| 145 top_left_corner_(NULL), | 144 top_left_corner_(NULL), |
| 146 top_edge_(NULL), | 145 top_edge_(NULL), |
| 147 top_right_corner_(NULL), | 146 top_right_corner_(NULL), |
| 148 header_left_edge_(NULL), | 147 header_left_edge_(NULL), |
| 149 header_right_edge_(NULL), | 148 header_right_edge_(NULL), |
| 150 previous_theme_frame_id_(0), | 149 previous_theme_frame_id_(0), |
| 151 previous_theme_frame_overlay_id_(0), | 150 previous_theme_frame_overlay_id_(0), |
| 152 crossfade_theme_frame_id_(0), | 151 crossfade_theme_frame_id_(0), |
| 153 crossfade_theme_frame_overlay_id_(0) {} | 152 crossfade_theme_frame_overlay_id_(0) {} |
| 154 | 153 |
| 155 HeaderPainter::~HeaderPainter() { | 154 HeaderPainter::~HeaderPainter() { |
| 156 // Sometimes we are destroyed before the window closes, so ensure we clean up. | |
| 157 if (window_) | |
| 158 window_->RemoveObserver(this); | |
| 159 } | 155 } |
| 160 | 156 |
| 161 void HeaderPainter::Init( | 157 void HeaderPainter::Init( |
| 162 views::Widget* frame, | 158 views::Widget* frame, |
| 163 views::View* header_view, | 159 views::View* header_view, |
| 164 views::View* window_icon, | 160 views::View* window_icon, |
| 165 FrameCaptionButtonContainerView* caption_button_container) { | 161 FrameCaptionButtonContainerView* caption_button_container) { |
| 166 DCHECK(frame); | 162 DCHECK(frame); |
| 167 DCHECK(header_view); | 163 DCHECK(header_view); |
| 168 // window_icon may be NULL. | 164 // window_icon may be NULL. |
| 169 DCHECK(caption_button_container); | 165 DCHECK(caption_button_container); |
| 170 frame_ = frame; | 166 frame_ = frame; |
| 171 header_view_ = header_view; | 167 header_view_ = header_view; |
| 172 window_icon_ = window_icon; | 168 window_icon_ = window_icon; |
| 173 caption_button_container_ = caption_button_container; | 169 caption_button_container_ = caption_button_container; |
| 174 | 170 |
| 175 // Window frame image parts. | 171 // Window frame image parts. |
| 176 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | 172 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
| 177 top_left_corner_ = | 173 top_left_corner_ = |
| 178 rb.GetImageNamed(IDR_AURA_WINDOW_HEADER_SHADE_TOP_LEFT).ToImageSkia(); | 174 rb.GetImageNamed(IDR_AURA_WINDOW_HEADER_SHADE_TOP_LEFT).ToImageSkia(); |
| 179 top_edge_ = | 175 top_edge_ = |
| 180 rb.GetImageNamed(IDR_AURA_WINDOW_HEADER_SHADE_TOP).ToImageSkia(); | 176 rb.GetImageNamed(IDR_AURA_WINDOW_HEADER_SHADE_TOP).ToImageSkia(); |
| 181 top_right_corner_ = | 177 top_right_corner_ = |
| 182 rb.GetImageNamed(IDR_AURA_WINDOW_HEADER_SHADE_TOP_RIGHT).ToImageSkia(); | 178 rb.GetImageNamed(IDR_AURA_WINDOW_HEADER_SHADE_TOP_RIGHT).ToImageSkia(); |
| 183 header_left_edge_ = | 179 header_left_edge_ = |
| 184 rb.GetImageNamed(IDR_AURA_WINDOW_HEADER_SHADE_LEFT).ToImageSkia(); | 180 rb.GetImageNamed(IDR_AURA_WINDOW_HEADER_SHADE_LEFT).ToImageSkia(); |
| 185 header_right_edge_ = | 181 header_right_edge_ = |
| 186 rb.GetImageNamed(IDR_AURA_WINDOW_HEADER_SHADE_RIGHT).ToImageSkia(); | 182 rb.GetImageNamed(IDR_AURA_WINDOW_HEADER_SHADE_RIGHT).ToImageSkia(); |
| 187 | |
| 188 window_ = frame->GetNativeWindow(); | |
| 189 | |
| 190 // Observer removes itself in OnWindowDestroying() below, or in the destructor | |
| 191 // if we go away before the window. | |
| 192 window_->AddObserver(this); | |
| 193 | |
| 194 // Solo-window header updates are handled by the WorkspaceLayoutManager when | |
| 195 // this window is added to the desktop. | |
| 196 } | 183 } |
| 197 | 184 |
| 198 // static | 185 // static |
| 199 gfx::Rect HeaderPainter::GetBoundsForClientView( | 186 gfx::Rect HeaderPainter::GetBoundsForClientView( |
| 200 int header_height, | 187 int header_height, |
| 201 const gfx::Rect& window_bounds) { | 188 const gfx::Rect& window_bounds) { |
| 202 gfx::Rect client_bounds(window_bounds); | 189 gfx::Rect client_bounds(window_bounds); |
| 203 client_bounds.Inset(0, header_height, 0, 0); | 190 client_bounds.Inset(0, header_height, 0, 0); |
| 204 return client_bounds; | 191 return client_bounds; |
| 205 } | 192 } |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 327 theme_frame, | 314 theme_frame, |
| 328 theme_frame_overlay, | 315 theme_frame_overlay, |
| 329 paint, | 316 paint, |
| 330 GetHeaderLocalBounds(), | 317 GetHeaderLocalBounds(), |
| 331 corner_radius, | 318 corner_radius, |
| 332 GetThemeBackgroundXInset()); | 319 GetThemeBackgroundXInset()); |
| 333 | 320 |
| 334 previous_theme_frame_id_ = theme_frame_id; | 321 previous_theme_frame_id_ = theme_frame_id; |
| 335 previous_theme_frame_overlay_id_ = theme_frame_overlay_id; | 322 previous_theme_frame_overlay_id_ = theme_frame_overlay_id; |
| 336 | 323 |
| 337 // We don't need the extra lightness in the edges when we're at the top edge | 324 // We don't need the extra lightness in the edges when the window is maximized |
| 338 // of the screen or when the header's corners are not rounded. | 325 // or fullscreen. |
| 339 // | 326 if (frame_->IsMaximized() || frame_->IsFullscreen()) |
| 340 // TODO(sky): this isn't quite right. What we really want is a method that | |
| 341 // returns bounds ignoring transforms on certain windows (such as workspaces) | |
| 342 // and is relative to the root. | |
| 343 if (frame_->GetNativeWindow()->bounds().y() == 0 || corner_radius == 0) | |
| 344 return; | 327 return; |
| 345 | 328 |
| 346 // Draw the top corners and edge. | 329 // Draw the top corners and edge. |
| 347 int top_left_width = top_left_corner_->width(); | 330 int top_left_width = top_left_corner_->width(); |
| 348 int top_left_height = top_left_corner_->height(); | 331 int top_left_height = top_left_corner_->height(); |
| 349 canvas->DrawImageInt(*top_left_corner_, | 332 canvas->DrawImageInt(*top_left_corner_, |
| 350 0, 0, top_left_width, top_left_height, | 333 0, 0, top_left_width, top_left_height, |
| 351 0, 0, top_left_width, top_left_height, | 334 0, 0, top_left_width, top_left_height, |
| 352 false); | 335 false); |
| 353 canvas->TileImageInt(*top_edge_, | 336 canvas->TileImageInt(*top_edge_, |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 448 previous_theme_frame_id_ = 0; | 431 previous_theme_frame_id_ = 0; |
| 449 previous_theme_frame_overlay_id_ = 0; | 432 previous_theme_frame_overlay_id_ = 0; |
| 450 | 433 |
| 451 if (crossfade_animation_.get() && crossfade_animation_->is_animating()) { | 434 if (crossfade_animation_.get() && crossfade_animation_->is_animating()) { |
| 452 crossfade_animation_.reset(); | 435 crossfade_animation_.reset(); |
| 453 header_view_->SchedulePaintInRect(GetHeaderLocalBounds()); | 436 header_view_->SchedulePaintInRect(GetHeaderLocalBounds()); |
| 454 } | 437 } |
| 455 } | 438 } |
| 456 | 439 |
| 457 /////////////////////////////////////////////////////////////////////////////// | 440 /////////////////////////////////////////////////////////////////////////////// |
| 458 // aura::WindowObserver overrides: | |
| 459 | |
| 460 void HeaderPainter::OnWindowDestroying(aura::Window* destroying) { | |
| 461 DCHECK_EQ(window_, destroying); | |
| 462 | |
| 463 // Must be removed here and not in the destructor, as the aura::Window is | |
| 464 // already destroyed when our destructor runs. | |
| 465 window_->RemoveObserver(this); | |
| 466 | |
| 467 window_ = NULL; | |
| 468 } | |
| 469 | |
| 470 void HeaderPainter::OnWindowBoundsChanged(aura::Window* window, | |
| 471 const gfx::Rect& old_bounds, | |
| 472 const gfx::Rect& new_bounds) { | |
| 473 // TODO(sky): this isn't quite right. What we really want is a method that | |
| 474 // returns bounds ignoring transforms on certain windows (such as workspaces). | |
| 475 if ((!frame_->IsMaximized() && !frame_->IsFullscreen()) && | |
| 476 ((old_bounds.y() == 0 && new_bounds.y() != 0) || | |
| 477 (old_bounds.y() != 0 && new_bounds.y() == 0))) { | |
| 478 SchedulePaintForHeader(); | |
| 479 } | |
| 480 } | |
| 481 | |
| 482 /////////////////////////////////////////////////////////////////////////////// | |
| 483 // gfx::AnimationDelegate overrides: | 441 // gfx::AnimationDelegate overrides: |
| 484 | 442 |
| 485 void HeaderPainter::AnimationProgressed(const gfx::Animation* animation) { | 443 void HeaderPainter::AnimationProgressed(const gfx::Animation* animation) { |
| 486 header_view_->SchedulePaintInRect(GetHeaderLocalBounds()); | 444 header_view_->SchedulePaintInRect(GetHeaderLocalBounds()); |
| 487 } | 445 } |
| 488 | 446 |
| 489 /////////////////////////////////////////////////////////////////////////////// | 447 /////////////////////////////////////////////////////////////////////////////// |
| 490 // HeaderPainter, private: | 448 // HeaderPainter, private: |
| 491 | 449 |
| 492 gfx::Rect HeaderPainter::GetHeaderLocalBounds() const { | 450 gfx::Rect HeaderPainter::GetHeaderLocalBounds() const { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 503 return caption_button_container_->y() + | 461 return caption_button_container_->y() + |
| 504 caption_button_container_->height() / 2; | 462 caption_button_container_->height() / 2; |
| 505 } | 463 } |
| 506 | 464 |
| 507 int HeaderPainter::GetHeaderCornerRadius() const { | 465 int HeaderPainter::GetHeaderCornerRadius() const { |
| 508 bool square_corners = (frame_->IsMaximized() || frame_->IsFullscreen()); | 466 bool square_corners = (frame_->IsMaximized() || frame_->IsFullscreen()); |
| 509 const int kCornerRadius = 2; | 467 const int kCornerRadius = 2; |
| 510 return square_corners ? 0 : kCornerRadius; | 468 return square_corners ? 0 : kCornerRadius; |
| 511 } | 469 } |
| 512 | 470 |
| 513 void HeaderPainter::SchedulePaintForHeader() { | |
| 514 int top_left_height = top_left_corner_->height(); | |
| 515 int top_right_height = top_right_corner_->height(); | |
| 516 header_view_->SchedulePaintInRect( | |
| 517 gfx::Rect(0, 0, header_view_->width(), | |
| 518 std::max(top_left_height, top_right_height))); | |
| 519 } | |
| 520 | |
| 521 gfx::Rect HeaderPainter::GetTitleBounds(const gfx::Font& title_font) { | 471 gfx::Rect HeaderPainter::GetTitleBounds(const gfx::Font& title_font) { |
| 522 int title_x = GetTitleOffsetX(); | 472 int title_x = GetTitleOffsetX(); |
| 523 // Center the text with respect to the caption button container. This way it | 473 // Center the text with respect to the caption button container. This way it |
| 524 // adapts to the caption button height and aligns exactly with the window | 474 // adapts to the caption button height and aligns exactly with the window |
| 525 // icon. Don't use |window_icon_| for this computation as it may be NULL. | 475 // icon. Don't use |window_icon_| for this computation as it may be NULL. |
| 526 int title_y = GetCaptionButtonContainerCenterY() - title_font.GetHeight() / 2; | 476 int title_y = GetCaptionButtonContainerCenterY() - title_font.GetHeight() / 2; |
| 527 return gfx::Rect( | 477 return gfx::Rect( |
| 528 title_x, | 478 title_x, |
| 529 std::max(0, title_y), | 479 std::max(0, title_y), |
| 530 std::max(0, caption_button_container_->x() - kTitleLogoSpacing - title_x), | 480 std::max(0, caption_button_container_->x() - kTitleLogoSpacing - title_x), |
| 531 title_font.GetHeight()); | 481 title_font.GetHeight()); |
| 532 } | 482 } |
| 533 | 483 |
| 534 } // namespace ash | 484 } // namespace ash |
| OLD | NEW |