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
ash / system / time / calendar_up_next_view_background_painter.cc [blame]
// Copyright 2023 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/system/time/calendar_up_next_view_background_painter.h"
#include "cc/paint/paint_flags.h"
#include "ui/color/color_provider.h"
#include "ui/gfx/canvas.h"
#include "ui/views/view.h"
namespace ash {
namespace {
constexpr int kBackgroundCornerRadius = 24;
// Space for the top point of the background.
// We start drawing a rectangle 12dip off the top and then eventually curve up
// when drawing the circle. The top of the circle will be at y: 0.
constexpr float kTopOffset = 12.f;
} // namespace
CalendarUpNextViewBackground::CalendarUpNextViewBackground(ui::ColorId color_id)
: color_id_(color_id) {}
CalendarUpNextViewBackground::~CalendarUpNextViewBackground() = default;
SkPath CalendarUpNextViewBackground::GetPath(const gfx::Size& size) {
// First draw a rounded rectangle.
SkPath path;
gfx::RectF rect_f((gfx::SizeF(size)));
rect_f.set_y(kTopOffset);
SkRect rect = SkRect{rect_f.x(), rect_f.y(), rect_f.width(), rect_f.height()};
path.addRoundRect(
rect, (SkScalar[]){kBackgroundCornerRadius, kBackgroundCornerRadius,
kBackgroundCornerRadius, kBackgroundCornerRadius, 0.f,
0.f, 0.f, 0.f});
path.close();
// Cache center-x for positioning curves when size changes.
const float cx = rect_f.CenterPoint().x();
// y values are shared between both curves.
const float curve_bottom_y = kTopOffset;
const float curve_top_y = 7;
const float curve_control_point_y = 12.84f;
// Draw left curve.
const float left_curve_start_x = cx - 23.f;
const float left_curve_end_x = cx - 13.f;
const float left_curve_control_point_x = cx - 16.86f;
path.moveTo(left_curve_start_x, curve_bottom_y);
path.cubicTo(left_curve_start_x, curve_bottom_y, left_curve_control_point_x,
curve_control_point_y, left_curve_end_x, curve_top_y);
path.lineTo(left_curve_end_x, curve_bottom_y);
path.close();
// Draw right curve.
const float right_curve_start_x = cx + 13.f;
const float right_curve_end_x = cx + 23.f;
const float right_curve_control_point_x = cx + 16.86f;
path.moveTo(right_curve_start_x, curve_bottom_y);
path.lineTo(right_curve_start_x, curve_top_y);
path.cubicTo(right_curve_start_x, curve_top_y, right_curve_control_point_x,
curve_control_point_y, right_curve_end_x, curve_bottom_y);
path.close();
// Draw circle in the center.
constexpr float kRadius = 16.f;
path.addCircle(cx, /*y=*/kRadius, kRadius);
path.close();
return path;
}
void CalendarUpNextViewBackground::Paint(gfx::Canvas* canvas,
views::View* view) const {
// Setup paint.
cc::PaintFlags flags;
flags.setBlendMode(SkBlendMode::kSrcOver);
flags.setAntiAlias(true);
flags.setStyle(cc::PaintFlags::kFill_Style);
flags.setColor(view->GetColorProvider()->GetColor(color_id_));
// Get the path to draw on the canvas.
SkPath path = GetPath(view->GetLocalBounds().size());
// Draw the path.
canvas->DrawPath(path, flags);
}
void CalendarUpNextViewBackground::OnViewThemeChanged(views::View* view) {
SetNativeControlColor(view->GetColorProvider()->GetColor(color_id_));
view->SchedulePaint();
}
} // namespace ash