dot_indicator.cc 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. // Copyright 2022 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "ash/style/dot_indicator.h"
  5. #include "ui/compositor/layer.h"
  6. #include "ui/gfx/geometry/insets.h"
  7. #include "ui/gfx/scoped_canvas.h"
  8. #include "ui/gfx/skia_paint_util.h"
  9. namespace ash {
  10. namespace {
  11. // The shadow value installed on the dot indicator.
  12. const gfx::ShadowValues kIndicatorShadow =
  13. gfx::ShadowValue::MakeChromeOSSystemUIShadowValues(2);
  14. } // namespace
  15. DotIndicator::DotIndicator(SkColor indicator_color)
  16. : shadow_values_(kIndicatorShadow), indicator_color_(indicator_color) {
  17. SetPaintToLayer();
  18. layer()->SetFillsBoundsOpaquely(false);
  19. SetVisible(false);
  20. }
  21. DotIndicator::~DotIndicator() = default;
  22. void DotIndicator::SetColor(SkColor new_color) {
  23. indicator_color_ = new_color;
  24. SchedulePaint();
  25. }
  26. void DotIndicator::SetIndicatorBounds(gfx::Rect indicator_bounds) {
  27. // Include the shadow margin to the bounds.
  28. indicator_bounds.Inset(gfx::ShadowValue::GetMargin(shadow_values_));
  29. SetBoundsRect(indicator_bounds);
  30. }
  31. void DotIndicator::OnPaint(gfx::Canvas* canvas) {
  32. // Return early if the indicator bounds are not set yet.
  33. if (bounds().IsEmpty())
  34. return;
  35. gfx::ScopedCanvas scoped(canvas);
  36. canvas->SaveLayerAlpha(SK_AlphaOPAQUE);
  37. const float dsf = canvas->UndoDeviceScaleFactor();
  38. // Remove the shadow margin to get the indicator bounds without shadow.
  39. gfx::Rect bounds_without_shadow = bounds();
  40. gfx::Insets shadow_insets = -gfx::ShadowValue::GetMargin(shadow_values_);
  41. bounds_without_shadow.Inset(shadow_insets);
  42. float radius = bounds_without_shadow.width() / 2.0f;
  43. // Set the center of the dot with the shadow offset.
  44. gfx::PointF center =
  45. gfx::PointF(radius + shadow_insets.left(), radius + shadow_insets.top());
  46. center.Scale(dsf);
  47. // Fill the center.
  48. cc::PaintFlags flags;
  49. flags.setLooper(gfx::CreateShadowDrawLooper(shadow_values_));
  50. flags.setColor(indicator_color_);
  51. flags.setAntiAlias(true);
  52. canvas->DrawCircle(center, dsf * radius, flags);
  53. }
  54. } // namespace ash