123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- // Copyright 2021 The Chromium Authors. All rights reserved.
- // 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
|