glanceable_info_view.cc 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. // Copyright 2020 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/ambient/ui/glanceable_info_view.h"
  5. #include <memory>
  6. #include <string>
  7. #include "ash/ambient/model/ambient_backend_model.h"
  8. #include "ash/ambient/ui/ambient_view_delegate.h"
  9. #include "ash/ambient/ui/ambient_view_ids.h"
  10. #include "ash/ambient/util/ambient_util.h"
  11. #include "ash/shell.h"
  12. #include "ash/strings/grit/ash_strings.h"
  13. #include "ash/system/model/clock_model.h"
  14. #include "ash/system/model/system_tray_model.h"
  15. #include "ash/system/time/time_view.h"
  16. #include "ash/system/tray/tray_constants.h"
  17. #include "base/i18n/number_formatting.h"
  18. #include "base/strings/utf_string_conversions.h"
  19. #include "third_party/skia/include/core/SkColor.h"
  20. #include "ui/base/l10n/l10n_util.h"
  21. #include "ui/base/metadata/metadata_impl_macros.h"
  22. #include "ui/compositor/layer.h"
  23. #include "ui/gfx/font_list.h"
  24. #include "ui/gfx/geometry/insets.h"
  25. #include "ui/gfx/geometry/rect.h"
  26. #include "ui/gfx/image/image_skia_operations.h"
  27. #include "ui/views/background.h"
  28. #include "ui/views/border.h"
  29. #include "ui/views/controls/image_view.h"
  30. #include "ui/views/controls/label.h"
  31. #include "ui/views/layout/box_layout.h"
  32. #include "ui/views/view.h"
  33. namespace ash {
  34. namespace {
  35. // Appearance.
  36. constexpr int kSpacingBetweenTimeAndWeatherDip = 24;
  37. constexpr int kSpacingBetweenWeatherIconAndTempDip = 8;
  38. constexpr int kWeatherIconSizeDip = 32;
  39. // Typography.
  40. constexpr int kDefaultFontSizeDip = 64;
  41. constexpr int kWeatherTemperatureFontSizeDip = 32;
  42. // Returns the fontlist used for the time text.
  43. gfx::FontList GetTimeFontList(int font_size_dip) {
  44. int font_size_delta = font_size_dip - kDefaultFontSizeDip;
  45. return font_size_delta == 0
  46. ? ambient::util::GetDefaultFontlist()
  47. : ambient::util::GetDefaultFontlist().DeriveWithSizeDelta(
  48. font_size_delta);
  49. }
  50. // Returns the fontlist used for the temperature text.
  51. gfx::FontList GetWeatherTemperatureFontList() {
  52. int temperature_font_size_delta =
  53. kWeatherTemperatureFontSizeDip - kDefaultFontSizeDip;
  54. return ambient::util::GetDefaultFontlist().DeriveWithSizeDelta(
  55. temperature_font_size_delta);
  56. }
  57. int GetFontDescent(const gfx::FontList& font_list) {
  58. return font_list.GetHeight() - font_list.GetBaseline();
  59. }
  60. int GetTemperatureFontDescent() {
  61. return GetWeatherTemperatureFontList().GetHeight() -
  62. GetWeatherTemperatureFontList().GetBaseline();
  63. }
  64. } // namespace
  65. GlanceableInfoView::GlanceableInfoView(AmbientViewDelegate* delegate,
  66. int time_font_size_dip,
  67. SkColor time_temperature_font_color)
  68. : delegate_(delegate),
  69. time_font_size_dip_(time_font_size_dip),
  70. time_temperature_font_color_(time_temperature_font_color) {
  71. DCHECK(delegate);
  72. DCHECK_GT(time_font_size_dip_, 0);
  73. SetID(AmbientViewID::kAmbientGlanceableInfoView);
  74. auto* weather_model = delegate_->GetAmbientWeatherModel();
  75. scoped_weather_model_observer_.Observe(weather_model);
  76. InitLayout();
  77. if (!weather_model->weather_condition_icon().isNull()) {
  78. // already has weather info, show immediately.
  79. Show();
  80. }
  81. }
  82. GlanceableInfoView::~GlanceableInfoView() = default;
  83. void GlanceableInfoView::OnWeatherInfoUpdated() {
  84. Show();
  85. }
  86. void GlanceableInfoView::OnThemeChanged() {
  87. views::View::OnThemeChanged();
  88. gfx::ShadowValues text_shadow_values =
  89. ambient::util::GetTextShadowValues(GetColorProvider());
  90. time_view_->SetTextShadowValues(text_shadow_values);
  91. temperature_->SetShadows(text_shadow_values);
  92. }
  93. void GlanceableInfoView::Show() {
  94. AmbientWeatherModel* weather_model = delegate_->GetAmbientWeatherModel();
  95. // When ImageView has an |image_| with different size than the |image_size_|,
  96. // it will resize and draw the |image_|. The quality is not as good as if we
  97. // resize the |image_| to be the same as the |image_size_| with |RESIZE_BEST|
  98. // method.
  99. gfx::ImageSkia icon = weather_model->weather_condition_icon();
  100. gfx::ImageSkia icon_resized = gfx::ImageSkiaOperations::CreateResizedImage(
  101. icon, skia::ImageOperations::RESIZE_BEST,
  102. gfx::Size(kWeatherIconSizeDip, kWeatherIconSizeDip));
  103. weather_condition_icon_->SetImage(icon_resized);
  104. temperature_->SetText(GetTemperatureText());
  105. }
  106. std::u16string GlanceableInfoView::GetTemperatureText() const {
  107. AmbientWeatherModel* weather_model = delegate_->GetAmbientWeatherModel();
  108. if (weather_model->show_celsius()) {
  109. return l10n_util::GetStringFUTF16Int(
  110. IDS_ASH_AMBIENT_MODE_WEATHER_TEMPERATURE_IN_CELSIUS,
  111. static_cast<int>(weather_model->GetTemperatureInCelsius()));
  112. }
  113. return l10n_util::GetStringFUTF16Int(
  114. IDS_ASH_AMBIENT_MODE_WEATHER_TEMPERATURE_IN_FAHRENHEIT,
  115. static_cast<int>(weather_model->temperature_fahrenheit()));
  116. }
  117. void GlanceableInfoView::InitLayout() {
  118. // The children of |GlanceableInfoView| will be drawn on their own
  119. // layer instead of the layer of |PhotoView| with a solid black background.
  120. SetPaintToLayer();
  121. layer()->SetFillsBoundsOpaquely(false);
  122. views::BoxLayout* layout =
  123. SetLayoutManager(std::make_unique<views::BoxLayout>(
  124. views::BoxLayout::Orientation::kHorizontal));
  125. layout->set_main_axis_alignment(views::BoxLayout::MainAxisAlignment::kStart);
  126. layout->set_cross_axis_alignment(views::BoxLayout::CrossAxisAlignment::kEnd);
  127. gfx::Insets shadow_insets =
  128. gfx::ShadowValue::GetMargin(ambient::util::GetTextShadowValues(nullptr));
  129. // Inits the time view.
  130. time_view_ = AddChildView(
  131. std::make_unique<TimeView>(TimeView::ClockLayout::HORIZONTAL_CLOCK,
  132. Shell::Get()->system_tray_model()->clock()));
  133. gfx::FontList time_font_list = GetTimeFontList(time_font_size_dip_);
  134. time_view_->SetTextFont(time_font_list);
  135. time_view_->SetTextColor(time_temperature_font_color_,
  136. /*auto_color_readability_enabled=*/false);
  137. // Remove the internal spacing in `time_view_` and adjust spacing for shadows.
  138. time_view_->SetBorder(views::CreateEmptyBorder(gfx::Insets::TLBR(
  139. -kUnifiedTrayTextTopPadding, -kUnifiedTrayTimeLeftPadding, 0,
  140. kSpacingBetweenTimeAndWeatherDip + shadow_insets.right())));
  141. // Inits the icon view.
  142. weather_condition_icon_ = AddChildView(std::make_unique<views::ImageView>());
  143. const gfx::Size size = gfx::Size(kWeatherIconSizeDip, kWeatherIconSizeDip);
  144. weather_condition_icon_->SetSize(size);
  145. weather_condition_icon_->SetImageSize(size);
  146. constexpr int kIconInternalPaddingDip = 4;
  147. weather_condition_icon_->SetBorder(views::CreateEmptyBorder(gfx::Insets::TLBR(
  148. 0, 0,
  149. GetFontDescent(time_font_list) - shadow_insets.bottom() -
  150. kIconInternalPaddingDip,
  151. kSpacingBetweenWeatherIconAndTempDip + shadow_insets.left())));
  152. // Inits the temp view.
  153. temperature_ = AddChildView(std::make_unique<views::Label>());
  154. temperature_->SetAutoColorReadabilityEnabled(false);
  155. temperature_->SetEnabledColor(time_temperature_font_color_);
  156. temperature_->SetFontList(GetWeatherTemperatureFontList());
  157. temperature_->SetBorder(views::CreateEmptyBorder(gfx::Insets::TLBR(
  158. 0, 0, GetFontDescent(time_font_list) - GetTemperatureFontDescent(), 0)));
  159. }
  160. BEGIN_METADATA(GlanceableInfoView, views::View)
  161. END_METADATA
  162. } // namespace ash