#include "ash/system/power/battery_image_source.h"
#include <algorithm>
#include "ash/resources/vector_icons/vector_icons.h"
#include "ash/style/ash_color_provider.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/geometry/rect_conversions.h"
#include "ui/gfx/geometry/rect_f.h"
#include "ui/gfx/geometry/skia_conversions.h"
#include "ui/gfx/paint_vector_icon.h"
namespace {
const int kMinVisualChargeLevel = 1;
constexpr gfx::RectF kDefaultFillRect = gfx::RectF(7, 6, 6, 10);
inline SkColor GetBatteryBadgeColor() {
return ash::AshColorProvider::Get()->GetContentLayerColor(
ash::AshColorProvider::ContentLayerType::kBatteryBadgeColor);
}
inline SkColor GetAlertColor() {
return ash::AshColorProvider::Get()->GetContentLayerColor(
ash::AshColorProvider::ContentLayerType::kIconColorAlert);
}
}
namespace ash {
BatteryImageSource::BatteryImageSource(
const PowerStatus::BatteryImageInfo& info,
int height,
SkColor fg_color,
absl::optional<SkColor> badge_color)
: gfx::CanvasImageSource(gfx::Size(height, height)),
info_(info),
fg_color_(fg_color),
badge_color_(badge_color.value_or(
info.charge_percent > 50 ? GetBatteryBadgeColor() : fg_color)) {}
BatteryImageSource::~BatteryImageSource() = default;
void BatteryImageSource::Draw(gfx::Canvas* canvas) {
PaintVectorIcon(canvas, kBatteryIcon, size().height(), fg_color_);
canvas->Save();
const float dsf = canvas->UndoDeviceScaleFactor();
const float kAssumedCanvasSize = 20;
const float const_scale = dsf * size().height() / kAssumedCanvasSize;
SkPath path;
gfx::RectF fill_rect = kDefaultFillRect;
fill_rect.Scale(const_scale);
path.addRect(gfx::RectToSkRect(gfx::ToEnclosingRect(fill_rect)));
cc::PaintFlags flags;
SkRect icon_bounds = path.getBounds();
float charge_level =
std::floor(info_.charge_percent / 100.0 * icon_bounds.height());
const float min_charge_level = dsf * kMinVisualChargeLevel;
charge_level =
std::clamp(charge_level, min_charge_level, icon_bounds.height());
const float charge_y = icon_bounds.bottom() - charge_level;
gfx::RectF clip_rect(0, charge_y, size().width() * dsf,
size().height() * dsf);
canvas->ClipRect(clip_rect);
const SkColor alert_color = GetAlertColor();
const bool use_alert_color =
charge_level == min_charge_level && info_.alert_if_low;
flags.setColor(use_alert_color ? alert_color : fg_color_);
canvas->DrawPath(path, flags);
canvas->Restore();
if (info_.badge_outline) {
PaintVectorIcon(canvas, *info_.badge_outline, size().height(),
SK_ColorBLUE);
}
if (info_.icon_badge) {
const SkColor badge_color = use_alert_color ? alert_color : fg_color_;
PaintVectorIcon(canvas, *info_.icon_badge, size().height(), badge_color);
}
}
bool BatteryImageSource::HasRepresentationAtAllScales() const {
return true;
}
}