| 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 "ash/wm/frame_painter.h" | 5 #include "ash/wm/frame_painter.h" |
| 6 | 6 |
| 7 #include "ash/shell.h" | 7 #include "ash/shell.h" |
| 8 #include "ash/shell_window_ids.h" | 8 #include "ash/shell_window_ids.h" |
| 9 #include "ash/wm/window_util.h" | 9 #include "ash/wm/window_util.h" |
| 10 #include "base/logging.h" // DCHECK | 10 #include "base/logging.h" // DCHECK |
| 11 #include "grit/ui_resources.h" | 11 #include "grit/ui_resources.h" |
| 12 #include "third_party/skia/include/core/SkCanvas.h" | 12 #include "third_party/skia/include/core/SkCanvas.h" |
| 13 #include "third_party/skia/include/core/SkColor.h" | 13 #include "third_party/skia/include/core/SkColor.h" |
| 14 #include "third_party/skia/include/core/SkPaint.h" | 14 #include "third_party/skia/include/core/SkPaint.h" |
| 15 #include "third_party/skia/include/core/SkPath.h" | 15 #include "third_party/skia/include/core/SkPath.h" |
| 16 #include "third_party/skia/include/core/SkShader.h" | 16 #include "third_party/skia/include/core/SkShader.h" |
| 17 #include "ui/aura/client/aura_constants.h" | 17 #include "ui/aura/client/aura_constants.h" |
| 18 #include "ui/aura/window.h" | 18 #include "ui/aura/window.h" |
| 19 #include "ui/base/animation/slide_animation.h" |
| 19 #include "ui/base/hit_test.h" | 20 #include "ui/base/hit_test.h" |
| 20 #include "ui/base/resource/resource_bundle.h" | 21 #include "ui/base/resource/resource_bundle.h" |
| 21 #include "ui/base/theme_provider.h" | 22 #include "ui/base/theme_provider.h" |
| 22 #include "ui/gfx/canvas.h" | 23 #include "ui/gfx/canvas.h" |
| 23 #include "ui/gfx/font.h" | 24 #include "ui/gfx/font.h" |
| 24 #include "ui/gfx/image/image.h" | 25 #include "ui/gfx/image/image.h" |
| 25 #include "ui/views/controls/button/image_button.h" | 26 #include "ui/views/controls/button/image_button.h" |
| 26 #include "ui/views/widget/widget.h" | 27 #include "ui/views/widget/widget.h" |
| 27 #include "ui/views/widget/widget_delegate.h" | 28 #include "ui/views/widget/widget_delegate.h" |
| 28 | 29 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 63 const int kCloseButtonOffsetX = 0; | 64 const int kCloseButtonOffsetX = 0; |
| 64 // Space between close button and top edge of window. | 65 // Space between close button and top edge of window. |
| 65 const int kCloseButtonOffsetY = 0; | 66 const int kCloseButtonOffsetY = 0; |
| 66 // In the pre-Ash era the web content area had a frame along the left edge, so | 67 // In the pre-Ash era the web content area had a frame along the left edge, so |
| 67 // user-generated theme images for the new tab page assume they are shifted | 68 // user-generated theme images for the new tab page assume they are shifted |
| 68 // right relative to the header. Now that we have removed the left edge frame | 69 // right relative to the header. Now that we have removed the left edge frame |
| 69 // we need to copy the theme image for the window header from a few pixels | 70 // we need to copy the theme image for the window header from a few pixels |
| 70 // inset to preserve alignment with the NTP image, or else we'll break a bunch | 71 // inset to preserve alignment with the NTP image, or else we'll break a bunch |
| 71 // of existing themes. We do something similar on OS X for the same reason. | 72 // of existing themes. We do something similar on OS X for the same reason. |
| 72 const int kThemeFrameBitmapOffsetX = 5; | 73 const int kThemeFrameBitmapOffsetX = 5; |
| 74 // Duration of crossfade animation for activating and deactivating frame. |
| 75 const int kActivationCrossfadeDurationMs = 200; |
| 73 | 76 |
| 74 // Tiles an image into an area, rounding the top corners. Samples the |bitmap| | 77 // Tiles an image into an area, rounding the top corners. Samples the |bitmap| |
| 75 // starting |bitmap_offset_x| pixels from the left of the image. | 78 // starting |bitmap_offset_x| pixels from the left of the image. |
| 76 void TileRoundRect(gfx::Canvas* canvas, | 79 void TileRoundRect(gfx::Canvas* canvas, |
| 77 int x, int y, int w, int h, | 80 int x, int y, int w, int h, |
| 78 SkPaint* paint, | 81 SkPaint* paint, |
| 79 const SkBitmap& bitmap, | 82 const SkBitmap& bitmap, |
| 80 int corner_radius, | 83 int corner_radius, |
| 81 int bitmap_offset_x) { | 84 int bitmap_offset_x) { |
| 82 // To get the shader to sample the image |inset_y| pixels in but tile across | 85 // To get the shader to sample the image |inset_y| pixels in but tile across |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 131 : frame_(NULL), | 134 : frame_(NULL), |
| 132 window_icon_(NULL), | 135 window_icon_(NULL), |
| 133 maximize_button_(NULL), | 136 maximize_button_(NULL), |
| 134 close_button_(NULL), | 137 close_button_(NULL), |
| 135 window_(NULL), | 138 window_(NULL), |
| 136 button_separator_(NULL), | 139 button_separator_(NULL), |
| 137 top_left_corner_(NULL), | 140 top_left_corner_(NULL), |
| 138 top_edge_(NULL), | 141 top_edge_(NULL), |
| 139 top_right_corner_(NULL), | 142 top_right_corner_(NULL), |
| 140 header_left_edge_(NULL), | 143 header_left_edge_(NULL), |
| 141 header_right_edge_(NULL) { | 144 header_right_edge_(NULL), |
| 145 previous_theme_frame_(NULL), |
| 146 previous_opacity_(0), |
| 147 crossfade_theme_frame_(NULL), |
| 148 crossfade_opacity_(0), |
| 149 crossfade_animation_(NULL) { |
| 142 if (!instances_) | 150 if (!instances_) |
| 143 instances_ = new std::set<FramePainter*>(); | 151 instances_ = new std::set<FramePainter*>(); |
| 144 instances_->insert(this); | 152 instances_->insert(this); |
| 145 } | 153 } |
| 146 | 154 |
| 147 FramePainter::~FramePainter() { | 155 FramePainter::~FramePainter() { |
| 148 // Sometimes we are destroyed before the window closes, so ensure we clean up. | 156 // Sometimes we are destroyed before the window closes, so ensure we clean up. |
| 149 if (window_) | 157 if (window_) |
| 150 window_->RemoveObserver(this); | 158 window_->RemoveObserver(this); |
| 151 instances_->erase(this); | 159 instances_->erase(this); |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 276 | 284 |
| 277 void FramePainter::PaintHeader(views::NonClientFrameView* view, | 285 void FramePainter::PaintHeader(views::NonClientFrameView* view, |
| 278 gfx::Canvas* canvas, | 286 gfx::Canvas* canvas, |
| 279 HeaderMode header_mode, | 287 HeaderMode header_mode, |
| 280 const SkBitmap* theme_frame, | 288 const SkBitmap* theme_frame, |
| 281 const SkBitmap* theme_frame_overlay) { | 289 const SkBitmap* theme_frame_overlay) { |
| 282 int opacity = UseSoloWindowHeader(NULL) ? | 290 int opacity = UseSoloWindowHeader(NULL) ? |
| 283 kSoloWindowOpacity : | 291 kSoloWindowOpacity : |
| 284 (header_mode == ACTIVE ? kActiveWindowOpacity : kInactiveWindowOpacity); | 292 (header_mode == ACTIVE ? kActiveWindowOpacity : kInactiveWindowOpacity); |
| 285 | 293 |
| 294 if (previous_theme_frame_ && previous_theme_frame_ != theme_frame) { |
| 295 crossfade_animation_.reset(new ui::SlideAnimation(this)); |
| 296 crossfade_theme_frame_ = previous_theme_frame_; |
| 297 crossfade_opacity_ = previous_opacity_; |
| 298 crossfade_animation_->SetSlideDuration(kActivationCrossfadeDurationMs); |
| 299 crossfade_animation_->Show(); |
| 300 } |
| 301 |
| 302 header_frame_bounds_ = gfx::Rect(0, 0, view->width(), theme_frame->height()); |
| 303 |
| 304 const int kCornerRadius = 2; |
| 286 SkPaint paint; | 305 SkPaint paint; |
| 287 paint.setAlpha(opacity); | 306 |
| 307 if (crossfade_animation_.get() && crossfade_animation_->is_animating()) { |
| 308 double current_value = crossfade_animation_->GetCurrentValue(); |
| 309 int old_alpha = (1 - current_value) * crossfade_opacity_; |
| 310 int new_alpha = current_value * opacity; |
| 311 |
| 312 // Draw the old header background, clipping the corners to be rounded. |
| 313 paint.setAlpha(old_alpha); |
| 314 paint.setXfermodeMode(SkXfermode::kPlus_Mode); |
| 315 TileRoundRect(canvas, |
| 316 0, 0, view->width(), theme_frame->height(), |
| 317 &paint, |
| 318 *crossfade_theme_frame_, |
| 319 kCornerRadius, |
| 320 kThemeFrameBitmapOffsetX); |
| 321 |
| 322 paint.setAlpha(new_alpha); |
| 323 } else { |
| 324 paint.setAlpha(opacity); |
| 325 } |
| 326 |
| 288 // Draw the header background, clipping the corners to be rounded. | 327 // Draw the header background, clipping the corners to be rounded. |
| 289 const int kCornerRadius = 2; | |
| 290 TileRoundRect(canvas, | 328 TileRoundRect(canvas, |
| 291 0, 0, view->width(), theme_frame->height(), | 329 0, 0, view->width(), theme_frame->height(), |
| 292 &paint, | 330 &paint, |
| 293 *theme_frame, | 331 *theme_frame, |
| 294 kCornerRadius, | 332 kCornerRadius, |
| 295 kThemeFrameBitmapOffsetX); | 333 kThemeFrameBitmapOffsetX); |
| 296 | 334 |
| 335 previous_theme_frame_ = theme_frame; |
| 336 previous_opacity_ = opacity; |
| 337 |
| 297 // Draw the theme frame overlay, if available. | 338 // Draw the theme frame overlay, if available. |
| 298 if (theme_frame_overlay) | 339 if (theme_frame_overlay) |
| 299 canvas->DrawBitmapInt(*theme_frame_overlay, 0, 0); | 340 canvas->DrawBitmapInt(*theme_frame_overlay, 0, 0); |
| 300 | 341 |
| 301 // Separator between the maximize and close buttons. | 342 // Separator between the maximize and close buttons. |
| 302 canvas->DrawBitmapInt(*button_separator_, | 343 canvas->DrawBitmapInt(*button_separator_, |
| 303 close_button_->x() - button_separator_->width(), | 344 close_button_->x() - button_separator_->width(), |
| 304 close_button_->y()); | 345 close_button_->y()); |
| 305 | 346 |
| 306 // We don't need the extra lightness in the edges when we're maximized. | 347 // We don't need the extra lightness in the edges when we're maximized. |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 464 it != instances_->end(); | 505 it != instances_->end(); |
| 465 ++it) { | 506 ++it) { |
| 466 FramePainter* painter = *it; | 507 FramePainter* painter = *it; |
| 467 if (IsVisibleNormalWindow(painter->window_) && painter->frame_) | 508 if (IsVisibleNormalWindow(painter->window_) && painter->frame_) |
| 468 painter->frame_->non_client_view()->SchedulePaint(); | 509 painter->frame_->non_client_view()->SchedulePaint(); |
| 469 } | 510 } |
| 470 } | 511 } |
| 471 } | 512 } |
| 472 | 513 |
| 473 /////////////////////////////////////////////////////////////////////////////// | 514 /////////////////////////////////////////////////////////////////////////////// |
| 515 // ui::AnimationDelegate overrides: |
| 516 |
| 517 void FramePainter::AnimationProgressed(const ui::Animation* animation) { |
| 518 frame_->SchedulePaintInRect(gfx::Rect(header_frame_bounds_)); |
| 519 } |
| 520 |
| 521 /////////////////////////////////////////////////////////////////////////////// |
| 474 // FramePainter, private: | 522 // FramePainter, private: |
| 475 | 523 |
| 476 void FramePainter::SetButtonImages(views::ImageButton* button, | 524 void FramePainter::SetButtonImages(views::ImageButton* button, |
| 477 int normal_bitmap_id, | 525 int normal_bitmap_id, |
| 478 int hot_bitmap_id, | 526 int hot_bitmap_id, |
| 479 int pushed_bitmap_id) { | 527 int pushed_bitmap_id) { |
| 480 ui::ThemeProvider* theme_provider = frame_->GetThemeProvider(); | 528 ui::ThemeProvider* theme_provider = frame_->GetThemeProvider(); |
| 481 button->SetImage(views::CustomButton::BS_NORMAL, | 529 button->SetImage(views::CustomButton::BS_NORMAL, |
| 482 theme_provider->GetBitmapNamed(normal_bitmap_id)); | 530 theme_provider->GetBitmapNamed(normal_bitmap_id)); |
| 483 button->SetImage(views::CustomButton::BS_HOT, | 531 button->SetImage(views::CustomButton::BS_HOT, |
| (...skipping 22 matching lines...) Expand all Loading... |
| 506 if (*it != ignore && IsVisibleNormalWindow(*it)) { | 554 if (*it != ignore && IsVisibleNormalWindow(*it)) { |
| 507 normal_window_count++; | 555 normal_window_count++; |
| 508 if (normal_window_count > 1) | 556 if (normal_window_count > 1) |
| 509 return false; | 557 return false; |
| 510 } | 558 } |
| 511 } | 559 } |
| 512 return normal_window_count == 1; | 560 return normal_window_count == 1; |
| 513 } | 561 } |
| 514 | 562 |
| 515 } // namespace ash | 563 } // namespace ash |
| OLD | NEW |