File: gradient_layer_delegate.cc

package info (click to toggle)
chromium 120.0.6099.224-1~deb11u1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 6,112,112 kB
  • sloc: cpp: 32,907,025; ansic: 8,148,123; javascript: 3,679,536; python: 2,031,248; asm: 959,718; java: 804,675; xml: 617,256; sh: 111,417; objc: 100,835; perl: 88,443; cs: 53,032; makefile: 29,579; fortran: 24,137; php: 21,162; tcl: 21,147; sql: 20,809; ruby: 17,735; pascal: 12,864; yacc: 8,045; lisp: 3,388; lex: 1,323; ada: 727; awk: 329; jsp: 267; csh: 117; exp: 43; sed: 37
file content (103 lines) | stat: -rw-r--r-- 3,586 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ash/controls/gradient_layer_delegate.h"

#include "base/time/time.h"
#include "ui/compositor/paint_recorder.h"
#include "ui/gfx/animation/linear_animation.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/skia_paint_util.h"
#include "ui/views/paint_info.h"

namespace ash {

GradientLayerDelegate::GradientLayerDelegate(bool animate_in)
    : layer_(ui::LAYER_TEXTURED) {
  layer_.set_delegate(this);
  layer_.SetFillsBoundsOpaquely(false);

  if (animate_in) {
    animation_ = std::make_unique<gfx::LinearAnimation>(
        base::Milliseconds(50), gfx::LinearAnimation::kDefaultFrameRate,
        /*delegate=*/this);
    animation_->Start();
    // The animation is usually 2 or 3 frames. Instead of starting the animation
    // at 0.0, which results in a fully transparent frame in the beginning, use
    // an initial value so the first frame is partially opaque.
    animation_->SetCurrentValue(0.333);
  }
}

GradientLayerDelegate::~GradientLayerDelegate() {
  layer_.set_delegate(nullptr);
}

void GradientLayerDelegate::OnPaintLayer(const ui::PaintContext& context) {
  const gfx::Size size = layer()->size();

  views::PaintInfo paint_info =
      views::PaintInfo::CreateRootPaintInfo(context, size);
  const auto& paint_recording_size = paint_info.paint_recording_size();

  // Pass the scale factor when constructing PaintRecorder so the MaskLayer
  // size is not incorrectly rounded (see https://crbug.com/921274).
  ui::PaintRecorder recorder(
      context, paint_info.paint_recording_size(),
      static_cast<float>(paint_recording_size.width()) / size.width(),
      static_cast<float>(paint_recording_size.height()) / size.height(),
      nullptr);

  recorder.canvas()->DrawColor(SK_ColorBLACK, SkBlendMode::kSrc);

  if (!start_fade_zone_.zone_rect.IsEmpty())
    DrawFadeZone(start_fade_zone_, recorder.canvas());
  if (!end_fade_zone_.zone_rect.IsEmpty())
    DrawFadeZone(end_fade_zone_, recorder.canvas());
}

void GradientLayerDelegate::AnimationProgressed(
    const gfx::Animation* animation) {
  DCHECK_EQ(animation, animation_.get());

  // Schedule repaint of the affected areas.
  if (!start_fade_zone_.zone_rect.IsEmpty())
    layer_.SchedulePaint(start_fade_zone_.zone_rect);
  if (!end_fade_zone_.zone_rect.IsEmpty())
    layer_.SchedulePaint(end_fade_zone_.zone_rect);
}

void GradientLayerDelegate::DrawFadeZone(const FadeZone& fade_zone,
                                         gfx::Canvas* canvas) {
  gfx::Point start_point;
  gfx::Point end_point;
  if (fade_zone.is_horizontal) {
    start_point = gfx::Point(fade_zone.zone_rect.x(), 0);
    end_point = gfx::Point(fade_zone.zone_rect.right(), 0);
  } else {
    start_point = gfx::Point(0, fade_zone.zone_rect.y());
    end_point = gfx::Point(0, fade_zone.zone_rect.bottom());
  }

  cc::PaintFlags flags;
  flags.setBlendMode(SkBlendMode::kSrc);
  flags.setAntiAlias(false);

  SkColor target_color;
  if (animation_) {
    // Animation runs 0.0 to 1.0, so alpha runs 255 (opaque) to 0 (transparent).
    uint8_t alpha = (1.0 - animation_->GetCurrentValue()) * 255;
    target_color = SkColorSetA(SK_ColorTRANSPARENT, alpha);
  } else {
    target_color = SK_ColorTRANSPARENT;
  }

  flags.setShader(gfx::CreateGradientShader(
      start_point, end_point, fade_zone.fade_in ? target_color : SK_ColorBLACK,
      fade_zone.fade_in ? SK_ColorBLACK : target_color));

  canvas->DrawRect(fade_zone.zone_rect, flags);
}

}  // namespace ash