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 |