background.cc 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. // Copyright (c) 2012 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 "ui/views/background.h"
  5. #include <utility>
  6. #include "base/check.h"
  7. #include "base/scoped_observation.h"
  8. #include "build/build_config.h"
  9. #include "cc/paint/paint_flags.h"
  10. #include "ui/color/color_id.h"
  11. #include "ui/color/color_provider.h"
  12. #include "ui/gfx/canvas.h"
  13. #include "ui/gfx/color_utils.h"
  14. #include "ui/views/painter.h"
  15. #include "ui/views/view.h"
  16. #if BUILDFLAG(IS_WIN)
  17. #include "skia/ext/skia_utils_win.h"
  18. #endif
  19. namespace views {
  20. // SolidBackground is a trivial Background implementation that fills the
  21. // background in a solid color.
  22. class SolidBackground : public Background {
  23. public:
  24. explicit SolidBackground(SkColor color) { SetNativeControlColor(color); }
  25. SolidBackground(const SolidBackground&) = delete;
  26. SolidBackground& operator=(const SolidBackground&) = delete;
  27. void Paint(gfx::Canvas* canvas, View* view) const override {
  28. // Fill the background. Note that we don't constrain to the bounds as
  29. // canvas is already clipped for us.
  30. canvas->DrawColor(get_color());
  31. }
  32. };
  33. // Shared class for RoundedRectBackground and ThemedRoundedRectBackground.
  34. class BaseRoundedRectBackground : public Background {
  35. public:
  36. BaseRoundedRectBackground(float radius, int for_border_thickness)
  37. : radius_(radius), half_thickness_(for_border_thickness / 2.0f) {}
  38. BaseRoundedRectBackground(const BaseRoundedRectBackground&) = delete;
  39. BaseRoundedRectBackground& operator=(const BaseRoundedRectBackground&) =
  40. delete;
  41. void Paint(gfx::Canvas* canvas, View* view) const override {
  42. cc::PaintFlags flags;
  43. flags.setAntiAlias(true);
  44. flags.setStyle(cc::PaintFlags::kFill_Style);
  45. flags.setColor(get_color());
  46. gfx::RectF bounds(view->GetLocalBounds());
  47. bounds.Inset(half_thickness_);
  48. canvas->DrawRoundRect(bounds, radius_ - half_thickness_, flags);
  49. }
  50. private:
  51. float radius_;
  52. float half_thickness_;
  53. };
  54. // RoundedRectBackground is a filled solid colored background that has
  55. // rounded corners.
  56. class RoundedRectBackground : public BaseRoundedRectBackground {
  57. public:
  58. RoundedRectBackground(SkColor color, float radius, int for_border_thickness)
  59. : BaseRoundedRectBackground(radius, for_border_thickness) {
  60. SetNativeControlColor(color);
  61. }
  62. RoundedRectBackground(const RoundedRectBackground&) = delete;
  63. RoundedRectBackground& operator=(const RoundedRectBackground&) = delete;
  64. };
  65. // ThemedVectorIconBackground is an image drawn on the view's background using
  66. // ThemedVectorIcon to react to theme changes.
  67. class ThemedVectorIconBackground : public Background {
  68. public:
  69. explicit ThemedVectorIconBackground(const ui::ThemedVectorIcon& icon)
  70. : icon_(icon) {
  71. DCHECK(!icon_.empty());
  72. }
  73. ThemedVectorIconBackground(const ThemedVectorIconBackground&) = delete;
  74. ThemedVectorIconBackground& operator=(const ThemedVectorIconBackground&) =
  75. delete;
  76. void OnViewThemeChanged(View* view) override { view->SchedulePaint(); }
  77. void Paint(gfx::Canvas* canvas, View* view) const override {
  78. canvas->DrawImageInt(icon_.GetImageSkia(view->GetColorProvider()), 0, 0);
  79. }
  80. private:
  81. const ui::ThemedVectorIcon icon_;
  82. };
  83. // ThemedSolidBackground is a solid background that stays in sync with a view's
  84. // ColorProvider.
  85. class ThemedSolidBackground : public SolidBackground {
  86. public:
  87. explicit ThemedSolidBackground(ui::ColorId color_id)
  88. : SolidBackground(gfx::kPlaceholderColor), color_id_(color_id) {}
  89. ThemedSolidBackground(const ThemedSolidBackground&) = delete;
  90. ThemedSolidBackground& operator=(const ThemedSolidBackground&) = delete;
  91. ~ThemedSolidBackground() override = default;
  92. void OnViewThemeChanged(View* view) override {
  93. SetNativeControlColor(view->GetColorProvider()->GetColor(color_id_));
  94. view->SchedulePaint();
  95. }
  96. private:
  97. const ui::ColorId color_id_;
  98. };
  99. // ThemedRoundedRectBackground is a solid rounded rect background that stays in
  100. // sync with a view's ColorProvider.
  101. class ThemedRoundedRectBackground : public BaseRoundedRectBackground {
  102. public:
  103. ThemedRoundedRectBackground(ui::ColorId color_id,
  104. float radius,
  105. int for_border_thickness)
  106. : BaseRoundedRectBackground(radius, for_border_thickness),
  107. color_id_(color_id) {}
  108. ThemedRoundedRectBackground(const ThemedRoundedRectBackground&) = delete;
  109. ThemedRoundedRectBackground& operator=(const ThemedRoundedRectBackground&) =
  110. delete;
  111. ~ThemedRoundedRectBackground() override = default;
  112. void OnViewThemeChanged(View* view) override {
  113. SetNativeControlColor(view->GetColorProvider()->GetColor(color_id_));
  114. view->SchedulePaint();
  115. }
  116. private:
  117. const ui::ColorId color_id_;
  118. };
  119. class BackgroundPainter : public Background {
  120. public:
  121. explicit BackgroundPainter(std::unique_ptr<Painter> painter)
  122. : painter_(std::move(painter)) {
  123. DCHECK(painter_);
  124. }
  125. BackgroundPainter(const BackgroundPainter&) = delete;
  126. BackgroundPainter& operator=(const BackgroundPainter&) = delete;
  127. ~BackgroundPainter() override = default;
  128. void Paint(gfx::Canvas* canvas, View* view) const override {
  129. Painter::PaintPainterAt(canvas, painter_.get(), view->GetLocalBounds());
  130. }
  131. private:
  132. std::unique_ptr<Painter> painter_;
  133. };
  134. Background::Background() = default;
  135. Background::~Background() = default;
  136. void Background::SetNativeControlColor(SkColor color) {
  137. color_ = color;
  138. }
  139. void Background::OnViewThemeChanged(View* view) {}
  140. std::unique_ptr<Background> CreateSolidBackground(SkColor color) {
  141. return std::make_unique<SolidBackground>(color);
  142. }
  143. std::unique_ptr<Background> CreateRoundedRectBackground(
  144. SkColor color,
  145. float radius,
  146. int for_border_thickness) {
  147. return std::make_unique<RoundedRectBackground>(color, radius,
  148. for_border_thickness);
  149. }
  150. std::unique_ptr<Background> CreateThemedRoundedRectBackground(
  151. ui::ColorId color_id,
  152. float radius,
  153. int for_border_thickness) {
  154. return std::make_unique<ThemedRoundedRectBackground>(color_id, radius,
  155. for_border_thickness);
  156. }
  157. std::unique_ptr<Background> CreateThemedVectorIconBackground(
  158. const ui::ThemedVectorIcon& icon) {
  159. return std::make_unique<ThemedVectorIconBackground>(icon);
  160. }
  161. std::unique_ptr<Background> CreateThemedSolidBackground(ui::ColorId color_id) {
  162. return std::make_unique<ThemedSolidBackground>(color_id);
  163. }
  164. std::unique_ptr<Background> CreateBackgroundFromPainter(
  165. std::unique_ptr<Painter> painter) {
  166. return std::make_unique<BackgroundPainter>(std::move(painter));
  167. }
  168. } // namespace views