Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(403)

Side by Side Diff: ash/wm/header_painter.cc

Issue 123023002: Remove "solo window" feature (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ash/wm/header_painter.h ('k') | ash/wm/header_painter_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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"
11 #include "ash/wm/solo_window_tracker.h"
12 #include "base/logging.h" // DCHECK 11 #include "base/logging.h" // DCHECK
13 #include "grit/ash_resources.h" 12 #include "grit/ash_resources.h"
14 #include "third_party/skia/include/core/SkCanvas.h" 13 #include "third_party/skia/include/core/SkCanvas.h"
15 #include "third_party/skia/include/core/SkColor.h" 14 #include "third_party/skia/include/core/SkColor.h"
16 #include "third_party/skia/include/core/SkPaint.h" 15 #include "third_party/skia/include/core/SkPaint.h"
17 #include "third_party/skia/include/core/SkPath.h" 16 #include "third_party/skia/include/core/SkPath.h"
18 #include "ui/aura/window.h" 17 #include "ui/aura/window.h"
19 #include "ui/base/hit_test.h" 18 #include "ui/base/hit_test.h"
20 #include "ui/base/resource/resource_bundle.h" 19 #include "ui/base/resource/resource_bundle.h"
21 #include "ui/base/theme_provider.h" 20 #include "ui/base/theme_provider.h"
(...skipping 30 matching lines...) Expand all
52 const SkColor kHeaderContentSeparatorColor = SkColorSetRGB(128, 128, 128); 51 const SkColor kHeaderContentSeparatorColor = SkColorSetRGB(128, 128, 128);
53 // In the pre-Ash era the web content area had a frame along the left edge, so 52 // In the pre-Ash era the web content area had a frame along the left edge, so
54 // user-generated theme images for the new tab page assume they are shifted 53 // user-generated theme images for the new tab page assume they are shifted
55 // right relative to the header. Now that we have removed the left edge frame 54 // right relative to the header. Now that we have removed the left edge frame
56 // we need to copy the theme image for the window header from a few pixels 55 // we need to copy the theme image for the window header from a few pixels
57 // inset to preserve alignment with the NTP image, or else we'll break a bunch 56 // inset to preserve alignment with the NTP image, or else we'll break a bunch
58 // of existing themes. We do something similar on OS X for the same reason. 57 // of existing themes. We do something similar on OS X for the same reason.
59 const int kThemeFrameImageInsetX = 5; 58 const int kThemeFrameImageInsetX = 5;
60 // Duration of crossfade animation for activating and deactivating frame. 59 // Duration of crossfade animation for activating and deactivating frame.
61 const int kActivationCrossfadeDurationMs = 200; 60 const int kActivationCrossfadeDurationMs = 200;
62 // Alpha/opacity value for fully-opaque headers.
63 const int kFullyOpaque = 255;
64 61
65 // Tiles an image into an area, rounding the top corners. Samples |image| 62 // Tiles an image into an area, rounding the top corners. Samples |image|
66 // starting |image_inset_x| pixels from the left of the image. 63 // starting |image_inset_x| pixels from the left of the image.
67 void TileRoundRect(gfx::Canvas* canvas, 64 void TileRoundRect(gfx::Canvas* canvas,
68 const gfx::ImageSkia& image, 65 const gfx::ImageSkia& image,
69 const SkPaint& paint, 66 const SkPaint& paint,
70 const gfx::Rect& bounds, 67 const gfx::Rect& bounds,
71 int top_left_corner_radius, 68 int top_left_corner_radius,
72 int top_right_corner_radius, 69 int top_right_corner_radius,
73 int image_inset_x) { 70 int image_inset_x) {
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
128 temporary_canvas.DrawImageInt(*frame_overlay_image, 0, 0); 125 temporary_canvas.DrawImageInt(*frame_overlay_image, 0, 0);
129 TileRoundRect(canvas, gfx::ImageSkia(temporary_canvas.ExtractImageRep()), 126 TileRoundRect(canvas, gfx::ImageSkia(temporary_canvas.ExtractImageRep()),
130 paint, bounds, corner_radius, corner_radius, 0); 127 paint, bounds, corner_radius, corner_radius, 0);
131 } 128 }
132 } 129 }
133 130
134 } // namespace 131 } // namespace
135 132
136 namespace ash { 133 namespace ash {
137 134
138 // static
139 int HeaderPainter::kActiveWindowOpacity = 255; // 1.0
140 int HeaderPainter::kInactiveWindowOpacity = 255; // 1.0
141 int HeaderPainter::kSoloWindowOpacity = 77; // 0.3
142
143 /////////////////////////////////////////////////////////////////////////////// 135 ///////////////////////////////////////////////////////////////////////////////
144 // HeaderPainter, public: 136 // HeaderPainter, public:
145 137
146 HeaderPainter::HeaderPainter() 138 HeaderPainter::HeaderPainter()
147 : frame_(NULL), 139 : frame_(NULL),
148 header_view_(NULL), 140 header_view_(NULL),
149 window_icon_(NULL), 141 window_icon_(NULL),
150 caption_button_container_(NULL), 142 caption_button_container_(NULL),
151 window_(NULL), 143 window_(NULL),
152 header_height_(0), 144 header_height_(0),
153 top_left_corner_(NULL), 145 top_left_corner_(NULL),
154 top_edge_(NULL), 146 top_edge_(NULL),
155 top_right_corner_(NULL), 147 top_right_corner_(NULL),
156 header_left_edge_(NULL), 148 header_left_edge_(NULL),
157 header_right_edge_(NULL), 149 header_right_edge_(NULL),
158 previous_theme_frame_id_(0), 150 previous_theme_frame_id_(0),
159 previous_theme_frame_overlay_id_(0), 151 previous_theme_frame_overlay_id_(0),
160 previous_opacity_(0),
161 crossfade_theme_frame_id_(0), 152 crossfade_theme_frame_id_(0),
162 crossfade_theme_frame_overlay_id_(0), 153 crossfade_theme_frame_overlay_id_(0) {}
163 crossfade_opacity_(0) {}
164 154
165 HeaderPainter::~HeaderPainter() { 155 HeaderPainter::~HeaderPainter() {
166 // 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.
167 if (window_) 157 if (window_)
168 window_->RemoveObserver(this); 158 window_->RemoveObserver(this);
169 } 159 }
170 160
171 void HeaderPainter::Init( 161 void HeaderPainter::Init(
172 views::Widget* frame, 162 views::Widget* frame,
173 views::View* header_view, 163 views::View* header_view,
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
252 242
253 int HeaderPainter::GetRightInset() const { 243 int HeaderPainter::GetRightInset() const {
254 return caption_button_container_->GetPreferredSize().width(); 244 return caption_button_container_->GetPreferredSize().width();
255 } 245 }
256 246
257 int HeaderPainter::GetThemeBackgroundXInset() const { 247 int HeaderPainter::GetThemeBackgroundXInset() const {
258 return kThemeFrameImageInsetX; 248 return kThemeFrameImageInsetX;
259 } 249 }
260 250
261 void HeaderPainter::PaintHeader(gfx::Canvas* canvas, 251 void HeaderPainter::PaintHeader(gfx::Canvas* canvas,
262 HeaderMode header_mode,
263 int theme_frame_id, 252 int theme_frame_id,
264 int theme_frame_overlay_id) { 253 int theme_frame_overlay_id) {
265 bool initial_paint = (previous_theme_frame_id_ == 0); 254 bool initial_paint = (previous_theme_frame_id_ == 0);
266 if (!initial_paint && 255 if (!initial_paint &&
267 (previous_theme_frame_id_ != theme_frame_id || 256 (previous_theme_frame_id_ != theme_frame_id ||
268 previous_theme_frame_overlay_id_ != theme_frame_overlay_id)) { 257 previous_theme_frame_overlay_id_ != theme_frame_overlay_id)) {
269 aura::Window* parent = frame_->GetNativeWindow()->parent(); 258 aura::Window* parent = frame_->GetNativeWindow()->parent();
270 // Don't animate the header if the parent (a workspace) is already 259 // Don't animate the header if the parent (a workspace) is already
271 // animating. Doing so results in continually painting during the animation 260 // animating. Doing so results in continually painting during the animation
272 // and gives a slower frame rate. 261 // and gives a slower frame rate.
273 // TODO(sky): expose a better way to determine this rather than assuming 262 // TODO(sky): expose a better way to determine this rather than assuming
274 // the parent is a workspace. 263 // the parent is a workspace.
275 bool parent_animating = parent && 264 bool parent_animating = parent &&
276 (parent->layer()->GetAnimator()->IsAnimatingProperty( 265 (parent->layer()->GetAnimator()->IsAnimatingProperty(
277 ui::LayerAnimationElement::OPACITY) || 266 ui::LayerAnimationElement::OPACITY) ||
278 parent->layer()->GetAnimator()->IsAnimatingProperty( 267 parent->layer()->GetAnimator()->IsAnimatingProperty(
279 ui::LayerAnimationElement::VISIBILITY)); 268 ui::LayerAnimationElement::VISIBILITY));
280 if (!parent_animating) { 269 if (!parent_animating) {
281 crossfade_animation_.reset(new gfx::SlideAnimation(this)); 270 crossfade_animation_.reset(new gfx::SlideAnimation(this));
282 crossfade_theme_frame_id_ = previous_theme_frame_id_; 271 crossfade_theme_frame_id_ = previous_theme_frame_id_;
283 crossfade_theme_frame_overlay_id_ = previous_theme_frame_overlay_id_; 272 crossfade_theme_frame_overlay_id_ = previous_theme_frame_overlay_id_;
284 crossfade_opacity_ = previous_opacity_;
285 crossfade_animation_->SetSlideDuration(kActivationCrossfadeDurationMs); 273 crossfade_animation_->SetSlideDuration(kActivationCrossfadeDurationMs);
286 crossfade_animation_->Show(); 274 crossfade_animation_->Show();
287 } else { 275 } else {
288 crossfade_animation_.reset(); 276 crossfade_animation_.reset();
289 } 277 }
290 } 278 }
291 279
292 int opacity =
293 GetHeaderOpacity(header_mode, theme_frame_id, theme_frame_overlay_id);
294 ui::ThemeProvider* theme_provider = frame_->GetThemeProvider(); 280 ui::ThemeProvider* theme_provider = frame_->GetThemeProvider();
295 gfx::ImageSkia* theme_frame = theme_provider->GetImageSkiaNamed( 281 gfx::ImageSkia* theme_frame = theme_provider->GetImageSkiaNamed(
296 theme_frame_id); 282 theme_frame_id);
297 gfx::ImageSkia* theme_frame_overlay = NULL; 283 gfx::ImageSkia* theme_frame_overlay = NULL;
298 if (theme_frame_overlay_id != 0) { 284 if (theme_frame_overlay_id != 0) {
299 theme_frame_overlay = theme_provider->GetImageSkiaNamed( 285 theme_frame_overlay = theme_provider->GetImageSkiaNamed(
300 theme_frame_overlay_id); 286 theme_frame_overlay_id);
301 } 287 }
302 288
303 int corner_radius = GetHeaderCornerRadius(); 289 int corner_radius = GetHeaderCornerRadius();
304 SkPaint paint; 290 SkPaint paint;
305 291
306 if (crossfade_animation_.get() && crossfade_animation_->is_animating()) { 292 if (crossfade_animation_.get() && crossfade_animation_->is_animating()) {
307 gfx::ImageSkia* crossfade_theme_frame = 293 gfx::ImageSkia* crossfade_theme_frame =
308 theme_provider->GetImageSkiaNamed(crossfade_theme_frame_id_); 294 theme_provider->GetImageSkiaNamed(crossfade_theme_frame_id_);
309 gfx::ImageSkia* crossfade_theme_frame_overlay = NULL; 295 gfx::ImageSkia* crossfade_theme_frame_overlay = NULL;
310 if (crossfade_theme_frame_overlay_id_ != 0) { 296 if (crossfade_theme_frame_overlay_id_ != 0) {
311 crossfade_theme_frame_overlay = theme_provider->GetImageSkiaNamed( 297 crossfade_theme_frame_overlay = theme_provider->GetImageSkiaNamed(
312 crossfade_theme_frame_overlay_id_); 298 crossfade_theme_frame_overlay_id_);
313 } 299 }
314 if (!crossfade_theme_frame || 300 if (!crossfade_theme_frame ||
315 (crossfade_theme_frame_overlay_id_ != 0 && 301 (crossfade_theme_frame_overlay_id_ != 0 &&
316 !crossfade_theme_frame_overlay)) { 302 !crossfade_theme_frame_overlay)) {
317 // Reset the animation. This case occurs when the user switches the theme 303 // Reset the animation. This case occurs when the user switches the theme
318 // that they are using. 304 // that they are using.
319 crossfade_animation_.reset(); 305 crossfade_animation_.reset();
320 paint.setAlpha(opacity);
321 } else { 306 } else {
322 double current_value = crossfade_animation_->GetCurrentValue(); 307 int old_alpha = crossfade_animation_->CurrentValueBetween(255, 0);
323 int old_alpha = (1 - current_value) * crossfade_opacity_; 308 int new_alpha = 255 - old_alpha;
324 int new_alpha = current_value * opacity;
325 309
326 // Draw the old header background, clipping the corners to be rounded. 310 // Draw the old header background, clipping the corners to be rounded.
327 paint.setAlpha(old_alpha); 311 paint.setAlpha(old_alpha);
328 paint.setXfermodeMode(SkXfermode::kPlus_Mode); 312 paint.setXfermodeMode(SkXfermode::kPlus_Mode);
329 PaintFrameImagesInRoundRect(canvas, 313 PaintFrameImagesInRoundRect(canvas,
330 crossfade_theme_frame, 314 crossfade_theme_frame,
331 crossfade_theme_frame_overlay, 315 crossfade_theme_frame_overlay,
332 paint, 316 paint,
333 GetHeaderLocalBounds(), 317 GetHeaderLocalBounds(),
334 corner_radius, 318 corner_radius,
335 GetThemeBackgroundXInset()); 319 GetThemeBackgroundXInset());
336 320
337 paint.setAlpha(new_alpha); 321 paint.setAlpha(new_alpha);
338 } 322 }
339 } else {
340 paint.setAlpha(opacity);
341 } 323 }
342 324
343 // Draw the header background, clipping the corners to be rounded. 325 // Draw the header background, clipping the corners to be rounded.
344 PaintFrameImagesInRoundRect(canvas, 326 PaintFrameImagesInRoundRect(canvas,
345 theme_frame, 327 theme_frame,
346 theme_frame_overlay, 328 theme_frame_overlay,
347 paint, 329 paint,
348 GetHeaderLocalBounds(), 330 GetHeaderLocalBounds(),
349 corner_radius, 331 corner_radius,
350 GetThemeBackgroundXInset()); 332 GetThemeBackgroundXInset());
351 333
352 previous_theme_frame_id_ = theme_frame_id; 334 previous_theme_frame_id_ = theme_frame_id;
353 previous_theme_frame_overlay_id_ = theme_frame_overlay_id; 335 previous_theme_frame_overlay_id_ = theme_frame_overlay_id;
354 previous_opacity_ = opacity;
355 336
356 // We don't need the extra lightness in the edges when we're at the top edge 337 // We don't need the extra lightness in the edges when we're at the top edge
357 // of the screen or when the header's corners are not rounded. 338 // of the screen or when the header's corners are not rounded.
358 // 339 //
359 // TODO(sky): this isn't quite right. What we really want is a method that 340 // TODO(sky): this isn't quite right. What we really want is a method that
360 // returns bounds ignoring transforms on certain windows (such as workspaces) 341 // returns bounds ignoring transforms on certain windows (such as workspaces)
361 // and is relative to the root. 342 // and is relative to the root.
362 if (frame_->GetNativeWindow()->bounds().y() == 0 || corner_radius == 0) 343 if (frame_->GetNativeWindow()->bounds().y() == 0 || corner_radius == 0)
363 return; 344 return;
364 345
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
522 return caption_button_container_->y() + 503 return caption_button_container_->y() +
523 caption_button_container_->height() / 2; 504 caption_button_container_->height() / 2;
524 } 505 }
525 506
526 int HeaderPainter::GetHeaderCornerRadius() const { 507 int HeaderPainter::GetHeaderCornerRadius() const {
527 bool square_corners = (frame_->IsMaximized() || frame_->IsFullscreen()); 508 bool square_corners = (frame_->IsMaximized() || frame_->IsFullscreen());
528 const int kCornerRadius = 2; 509 const int kCornerRadius = 2;
529 return square_corners ? 0 : kCornerRadius; 510 return square_corners ? 0 : kCornerRadius;
530 } 511 }
531 512
532 int HeaderPainter::GetHeaderOpacity(
533 HeaderMode header_mode,
534 int theme_frame_id,
535 int theme_frame_overlay_id) const {
536 // User-provided themes are painted fully opaque.
537 ui::ThemeProvider* theme_provider = frame_->GetThemeProvider();
538 if (theme_provider->HasCustomImage(theme_frame_id) ||
539 (theme_frame_overlay_id != 0 &&
540 theme_provider->HasCustomImage(theme_frame_overlay_id))) {
541 return kFullyOpaque;
542 }
543
544 // Maximized and fullscreen windows are fully opaque.
545 if (frame_->IsMaximized() || frame_->IsFullscreen())
546 return kFullyOpaque;
547
548 // Solo header is very transparent.
549 ash::SoloWindowTracker* solo_window_tracker =
550 internal::RootWindowController::ForWindow(window_)->solo_window_tracker();
551 if (solo_window_tracker &&
552 solo_window_tracker->GetWindowWithSoloHeader() == window_) {
553 return kSoloWindowOpacity;
554 }
555
556 // Otherwise, change transparency based on window activation status.
557 if (header_mode == ACTIVE)
558 return kActiveWindowOpacity;
559 return kInactiveWindowOpacity;
560 }
561
562 void HeaderPainter::SchedulePaintForHeader() { 513 void HeaderPainter::SchedulePaintForHeader() {
563 int top_left_height = top_left_corner_->height(); 514 int top_left_height = top_left_corner_->height();
564 int top_right_height = top_right_corner_->height(); 515 int top_right_height = top_right_corner_->height();
565 header_view_->SchedulePaintInRect( 516 header_view_->SchedulePaintInRect(
566 gfx::Rect(0, 0, header_view_->width(), 517 gfx::Rect(0, 0, header_view_->width(),
567 std::max(top_left_height, top_right_height))); 518 std::max(top_left_height, top_right_height)));
568 } 519 }
569 520
570 gfx::Rect HeaderPainter::GetTitleBounds(const gfx::Font& title_font) { 521 gfx::Rect HeaderPainter::GetTitleBounds(const gfx::Font& title_font) {
571 int title_x = GetTitleOffsetX(); 522 int title_x = GetTitleOffsetX();
572 // Center the text with respect to the caption button container. This way it 523 // Center the text with respect to the caption button container. This way it
573 // adapts to the caption button height and aligns exactly with the window 524 // adapts to the caption button height and aligns exactly with the window
574 // icon. Don't use |window_icon_| for this computation as it may be NULL. 525 // icon. Don't use |window_icon_| for this computation as it may be NULL.
575 int title_y = GetCaptionButtonContainerCenterY() - title_font.GetHeight() / 2; 526 int title_y = GetCaptionButtonContainerCenterY() - title_font.GetHeight() / 2;
576 return gfx::Rect( 527 return gfx::Rect(
577 title_x, 528 title_x,
578 std::max(0, title_y), 529 std::max(0, title_y),
579 std::max(0, caption_button_container_->x() - kTitleLogoSpacing - title_x), 530 std::max(0, caption_button_container_->x() - kTitleLogoSpacing - title_x),
580 title_font.GetHeight()); 531 title_font.GetHeight());
581 } 532 }
582 533
583 } // namespace ash 534 } // namespace ash
OLDNEW
« no previous file with comments | « ash/wm/header_painter.h ('k') | ash/wm/header_painter_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698