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 "base/logging.h" // DCHECK | 7 #include "base/logging.h" // DCHECK |
8 #include "grit/ui_resources.h" | 8 #include "grit/ui_resources.h" |
9 #include "third_party/skia/include/core/SkCanvas.h" | 9 #include "third_party/skia/include/core/SkCanvas.h" |
10 #include "third_party/skia/include/core/SkColor.h" | 10 #include "third_party/skia/include/core/SkColor.h" |
11 #include "third_party/skia/include/core/SkPaint.h" | 11 #include "third_party/skia/include/core/SkPaint.h" |
12 #include "third_party/skia/include/core/SkPath.h" | 12 #include "third_party/skia/include/core/SkPath.h" |
13 #include "third_party/skia/include/core/SkShader.h" | 13 #include "third_party/skia/include/core/SkShader.h" |
14 #include "ui/aura/window.h" | 14 #include "ui/aura/window.h" |
15 #include "ui/base/animation/slide_animation.h" | |
15 #include "ui/base/hit_test.h" | 16 #include "ui/base/hit_test.h" |
16 #include "ui/base/resource/resource_bundle.h" | 17 #include "ui/base/resource/resource_bundle.h" |
17 #include "ui/base/theme_provider.h" | 18 #include "ui/base/theme_provider.h" |
18 #include "ui/gfx/canvas.h" | 19 #include "ui/gfx/canvas.h" |
19 #include "ui/gfx/font.h" | 20 #include "ui/gfx/font.h" |
20 #include "ui/gfx/image/image.h" | 21 #include "ui/gfx/image/image.h" |
21 #include "ui/views/controls/button/image_button.h" | 22 #include "ui/views/controls/button/image_button.h" |
22 #include "ui/views/widget/widget.h" | 23 #include "ui/views/widget/widget.h" |
23 #include "ui/views/widget/widget_delegate.h" | 24 #include "ui/views/widget/widget_delegate.h" |
24 | 25 |
(...skipping 27 matching lines...) Expand all Loading... | |
52 // Color for the title text. | 53 // Color for the title text. |
53 const SkColor kTitleColor = SkColorSetRGB(40, 40, 40); | 54 const SkColor kTitleColor = SkColorSetRGB(40, 40, 40); |
54 // Size of header/content separator line below the header image. | 55 // Size of header/content separator line below the header image. |
55 const int kHeaderContentSeparatorSize = 1; | 56 const int kHeaderContentSeparatorSize = 1; |
56 // Color of header bottom edge line. | 57 // Color of header bottom edge line. |
57 const SkColor kHeaderContentSeparatorColor = SkColorSetRGB(128, 128, 128); | 58 const SkColor kHeaderContentSeparatorColor = SkColorSetRGB(128, 128, 128); |
58 // Space between close button and right edge of window. | 59 // Space between close button and right edge of window. |
59 const int kCloseButtonOffsetX = 0; | 60 const int kCloseButtonOffsetX = 0; |
60 // Space between close button and top edge of window. | 61 // Space between close button and top edge of window. |
61 const int kCloseButtonOffsetY = 0; | 62 const int kCloseButtonOffsetY = 0; |
63 // Duration of crossfade animation for activating and deactivating frame. | |
64 const int kActivationCrossfadeDurationMS = 100; | |
James Cook
2012/03/19 19:25:58
I think the shadow animation uses 200 ms. Could y
pkotwicz
2012/03/20 00:59:46
Done.
| |
62 | 65 |
63 // Tiles an image into an area, rounding the top corners. | 66 // Tiles an image into an area, rounding the top corners. |
64 void TileRoundRect(gfx::Canvas* canvas, | 67 void TileRoundRect(gfx::Canvas* canvas, |
65 int x, int y, int w, int h, | 68 int x, int y, int w, int h, |
69 SkPaint paint, | |
James Cook
2012/03/19 19:25:58
Are these cheap to copy? If not, pass a pointer?
| |
66 const SkBitmap& bitmap, | 70 const SkBitmap& bitmap, |
67 int corner_radius) { | 71 int corner_radius) { |
68 SkRect rect; | 72 SkRect rect; |
69 rect.iset(x, y, x + w, y + h); | 73 rect.iset(x, y, x + w, y + h); |
70 const SkScalar kRadius = SkIntToScalar(corner_radius); | 74 const SkScalar kRadius = SkIntToScalar(corner_radius); |
71 SkScalar radii[8] = { | 75 SkScalar radii[8] = { |
72 kRadius, kRadius, // top-left | 76 kRadius, kRadius, // top-left |
73 kRadius, kRadius, // top-right | 77 kRadius, kRadius, // top-right |
74 0, 0, // bottom-right | 78 0, 0, // bottom-right |
75 0, 0}; // bottom-left | 79 0, 0}; // bottom-left |
76 SkPath path; | 80 SkPath path; |
77 path.addRoundRect(rect, radii, SkPath::kCW_Direction); | 81 path.addRoundRect(rect, radii, SkPath::kCW_Direction); |
78 | 82 |
79 SkPaint paint; | |
80 SkShader* shader = SkShader::CreateBitmapShader(bitmap, | 83 SkShader* shader = SkShader::CreateBitmapShader(bitmap, |
81 SkShader::kRepeat_TileMode, | 84 SkShader::kRepeat_TileMode, |
82 SkShader::kRepeat_TileMode); | 85 SkShader::kRepeat_TileMode); |
83 paint.setShader(shader); | 86 paint.setShader(shader); |
84 paint.setXfermodeMode(SkXfermode::kSrcOver_Mode); | |
85 // CreateBitmapShader returns a Shader with a reference count of one, we | 87 // CreateBitmapShader returns a Shader with a reference count of one, we |
86 // need to unref after paint takes ownership of the shader. | 88 // need to unref after paint takes ownership of the shader. |
87 shader->unref(); | 89 shader->unref(); |
88 canvas->sk_canvas()->drawPath(path, paint); | 90 canvas->sk_canvas()->drawPath(path, paint); |
89 } | 91 } |
90 } // namespace | 92 } // namespace |
91 | 93 |
92 namespace ash { | 94 namespace ash { |
93 | 95 |
94 /////////////////////////////////////////////////////////////////////////////// | 96 /////////////////////////////////////////////////////////////////////////////// |
95 // FramePainter, public: | 97 // FramePainter, public: |
96 | 98 |
97 FramePainter::FramePainter() | 99 FramePainter::FramePainter() |
98 : frame_(NULL), | 100 : frame_(NULL), |
99 window_icon_(NULL), | 101 window_icon_(NULL), |
100 maximize_button_(NULL), | 102 maximize_button_(NULL), |
101 close_button_(NULL), | 103 close_button_(NULL), |
102 button_separator_(NULL), | 104 button_separator_(NULL), |
103 top_left_corner_(NULL), | 105 top_left_corner_(NULL), |
104 top_edge_(NULL), | 106 top_edge_(NULL), |
105 top_right_corner_(NULL), | 107 top_right_corner_(NULL), |
106 header_left_edge_(NULL), | 108 header_left_edge_(NULL), |
107 header_right_edge_(NULL) { | 109 header_right_edge_(NULL), |
110 previous_theme_frame_(NULL), | |
111 crossfade_theme_frame_(NULL), | |
112 crossfade_animation_(NULL) { | |
108 } | 113 } |
109 | 114 |
110 FramePainter::~FramePainter() { | 115 FramePainter::~FramePainter() { |
111 } | 116 } |
112 | 117 |
113 void FramePainter::Init(views::Widget* frame, | 118 void FramePainter::Init(views::Widget* frame, |
114 views::View* window_icon, | 119 views::View* window_icon, |
115 views::ImageButton* maximize_button, | 120 views::ImageButton* maximize_button, |
116 views::ImageButton* close_button) { | 121 views::ImageButton* close_button) { |
117 DCHECK(frame); | 122 DCHECK(frame); |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
218 if (title_width > min_size.width()) | 223 if (title_width > min_size.width()) |
219 min_size.set_width(title_width); | 224 min_size.set_width(title_width); |
220 return min_size; | 225 return min_size; |
221 } | 226 } |
222 | 227 |
223 void FramePainter::PaintHeader(views::NonClientFrameView* view, | 228 void FramePainter::PaintHeader(views::NonClientFrameView* view, |
224 gfx::Canvas* canvas, | 229 gfx::Canvas* canvas, |
225 const SkBitmap* theme_frame, | 230 const SkBitmap* theme_frame, |
226 const SkBitmap* theme_frame_overlay) { | 231 const SkBitmap* theme_frame_overlay) { |
227 | 232 |
233 if (previous_theme_frame_ && previous_theme_frame_ != theme_frame) { | |
234 crossfade_animation_.reset(new ui::SlideAnimation(this)); | |
235 crossfade_theme_frame_ = previous_theme_frame_; | |
236 crossfade_animation_->Reset(); | |
James Cook
2012/03/19 19:25:58
Does the animation have to be reset if it was just
pkotwicz
2012/03/20 00:59:46
Done.
| |
237 crossfade_animation_->SetSlideDuration(kActivationCrossfadeDurationMS); | |
238 crossfade_animation_->Show(); | |
239 } | |
240 | |
241 header_frame_bounds_ = gfx::Rect(0, 0, view->width(), theme_frame->height()); | |
242 const int kCornerRadius = 2; | |
243 | |
244 SkPaint paint; | |
245 if (crossfade_animation_.get() && crossfade_animation_->is_animating()) { | |
246 uint8 theme_alpha = crossfade_animation_->GetCurrentValue() * 255; | |
247 | |
248 // Draw the old header background, clipping the corners to be rounded. | |
249 paint.setAlpha(255 - theme_alpha); | |
250 paint.setXfermodeMode(SkXfermode::kPlus_Mode); | |
251 TileRoundRect(canvas, | |
252 0, 0, view->width(), theme_frame->height(), | |
253 paint, | |
254 *crossfade_theme_frame_, | |
255 kCornerRadius); | |
256 | |
257 paint.setAlpha(theme_alpha); | |
258 } | |
259 | |
228 // Draw the header background, clipping the corners to be rounded. | 260 // Draw the header background, clipping the corners to be rounded. |
229 const int kCornerRadius = 2; | |
230 TileRoundRect(canvas, | 261 TileRoundRect(canvas, |
231 0, 0, view->width(), theme_frame->height(), | 262 0, 0, view->width(), theme_frame->height(), paint, |
232 *theme_frame, | 263 *theme_frame, |
233 kCornerRadius); | 264 kCornerRadius); |
234 | 265 |
266 previous_theme_frame_ = theme_frame; | |
267 | |
235 // Draw the theme frame overlay, if available. | 268 // Draw the theme frame overlay, if available. |
236 if (theme_frame_overlay) | 269 if (theme_frame_overlay) |
237 canvas->DrawBitmapInt(*theme_frame_overlay, 0, 0); | 270 canvas->DrawBitmapInt(*theme_frame_overlay, 0, 0); |
238 | 271 |
239 // Separator between the maximize and close buttons. | 272 // Separator between the maximize and close buttons. |
240 canvas->DrawBitmapInt(*button_separator_, | 273 canvas->DrawBitmapInt(*button_separator_, |
241 close_button_->x() - button_separator_->width(), | 274 close_button_->x() - button_separator_->width(), |
242 close_button_->y()); | 275 close_button_->y()); |
243 | 276 |
244 // Draw the top corners and edge. | 277 // Draw the top corners and edge. |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
351 close_button_->y(), | 384 close_button_->y(), |
352 maximize_size.width(), | 385 maximize_size.width(), |
353 maximize_size.height()); | 386 maximize_size.height()); |
354 | 387 |
355 if (window_icon_) | 388 if (window_icon_) |
356 window_icon_->SetBoundsRect( | 389 window_icon_->SetBoundsRect( |
357 gfx::Rect(kIconOffsetX, kIconOffsetY, kIconSize, kIconSize)); | 390 gfx::Rect(kIconOffsetX, kIconOffsetY, kIconSize, kIconSize)); |
358 } | 391 } |
359 | 392 |
360 /////////////////////////////////////////////////////////////////////////////// | 393 /////////////////////////////////////////////////////////////////////////////// |
394 // ui::AnimationDelegate overrides: | |
395 | |
396 void FramePainter::AnimationProgressed(const ui::Animation* animation) { | |
397 frame_->SchedulePaintInRect(gfx::Rect(header_frame_bounds_)); | |
398 } | |
399 | |
400 /////////////////////////////////////////////////////////////////////////////// | |
361 // FramePainter, private: | 401 // FramePainter, private: |
362 | 402 |
363 void FramePainter::SetButtonImages(views::ImageButton* button, | 403 void FramePainter::SetButtonImages(views::ImageButton* button, |
364 int normal_bitmap_id, | 404 int normal_bitmap_id, |
365 int hot_bitmap_id, | 405 int hot_bitmap_id, |
366 int pushed_bitmap_id) { | 406 int pushed_bitmap_id) { |
367 ui::ThemeProvider* theme_provider = frame_->GetThemeProvider(); | 407 ui::ThemeProvider* theme_provider = frame_->GetThemeProvider(); |
368 button->SetImage(views::CustomButton::BS_NORMAL, | 408 button->SetImage(views::CustomButton::BS_NORMAL, |
369 theme_provider->GetBitmapNamed(normal_bitmap_id)); | 409 theme_provider->GetBitmapNamed(normal_bitmap_id)); |
370 button->SetImage(views::CustomButton::BS_HOT, | 410 button->SetImage(views::CustomButton::BS_HOT, |
371 theme_provider->GetBitmapNamed(hot_bitmap_id)); | 411 theme_provider->GetBitmapNamed(hot_bitmap_id)); |
372 button->SetImage(views::CustomButton::BS_PUSHED, | 412 button->SetImage(views::CustomButton::BS_PUSHED, |
373 theme_provider->GetBitmapNamed(pushed_bitmap_id)); | 413 theme_provider->GetBitmapNamed(pushed_bitmap_id)); |
374 } | 414 } |
375 | 415 |
376 int FramePainter::GetTitleOffsetX() const { | 416 int FramePainter::GetTitleOffsetX() const { |
377 return window_icon_ ? | 417 return window_icon_ ? |
378 window_icon_->bounds().right() + kTitleIconOffsetX : | 418 window_icon_->bounds().right() + kTitleIconOffsetX : |
379 kTitleNoIconOffsetX; | 419 kTitleNoIconOffsetX; |
380 } | 420 } |
381 | 421 |
382 } // namespace ash | 422 } // namespace ash |
OLD | NEW |