Commit 71b9f0dc authored by Meilin Wang's avatar Meilin Wang Committed by Commit Bot

ambient: Add photo attribution (part 2).

Please see screenshot in the linked bug.

Bug: b/161481195
Test: manually.
Change-Id: Ie276b743b122d447cc658dfff6e72476122aef3f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2336493
Commit-Queue: Meilin Wang <meilinw@chromium.org>
Reviewed-by: default avatarXiaohui Chen <xiaohuic@chromium.org>
Cr-Commit-Position: refs/heads/master@{#797418}
parent 511d0529
...@@ -92,7 +92,7 @@ void AmbientBackendModel::Clear() { ...@@ -92,7 +92,7 @@ void AmbientBackendModel::Clear() {
next_image_.Clear(); next_image_.Clear();
} }
PhotoWithDetails AmbientBackendModel::GetNextImage() const { const PhotoWithDetails& AmbientBackendModel::GetNextImage() const {
if (!next_image_.IsNull()) if (!next_image_.IsNull())
return next_image_; return next_image_;
......
...@@ -67,7 +67,7 @@ class ASH_EXPORT AmbientBackendModel { ...@@ -67,7 +67,7 @@ class ASH_EXPORT AmbientBackendModel {
void Clear(); void Clear();
// Get images from local storage. Could be null image. // Get images from local storage. Could be null image.
PhotoWithDetails GetNextImage() const; const PhotoWithDetails& GetNextImage() const;
// Updates the weather information and notifies observers if the icon image is // Updates the weather information and notifies observers if the icon image is
// not null. // not null.
......
...@@ -4,18 +4,39 @@ ...@@ -4,18 +4,39 @@
#include "ash/ambient/ui/ambient_background_image_view.h" #include "ash/ambient/ui/ambient_background_image_view.h"
#include <memory>
#include "ash/ambient/util/ambient_util.h"
#include "ash/assistant/ui/assistant_view_ids.h" #include "ash/assistant/ui/assistant_view_ids.h"
#include "ui/events/event.h" #include "ui/events/event.h"
#include "ui/gfx/geometry/insets.h"
#include "ui/views/controls/image_view.h" #include "ui/views/controls/image_view.h"
#include "ui/views/controls/label.h"
#include "ui/views/layout/box_layout.h"
#include "ui/views/layout/fill_layout.h"
#include "ui/views/metadata/metadata_impl_macros.h" #include "ui/views/metadata/metadata_impl_macros.h"
namespace ash { namespace ash {
namespace {
// Appearance.
constexpr int kHorizontalMarginDip = 16;
constexpr int kVerticalMarginDip = 43;
// Typography.
constexpr SkColor kTextColor = SK_ColorWHITE;
constexpr int kDefaultFontSizeDip = 64;
constexpr int kDetailsFontSizeDip = 13;
} // namespace
AmbientBackgroundImageView::AmbientBackgroundImageView( AmbientBackgroundImageView::AmbientBackgroundImageView(
AmbientViewDelegate* delegate) AmbientViewDelegate* delegate)
: delegate_(delegate) { : delegate_(delegate) {
DCHECK(delegate_); DCHECK(delegate_);
SetID(AssistantViewID::kAmbientBackgroundImageView); SetID(AssistantViewID::kAmbientBackgroundImageView);
InitLayout();
} }
AmbientBackgroundImageView::~AmbientBackgroundImageView() = default; AmbientBackgroundImageView::~AmbientBackgroundImageView() = default;
...@@ -34,6 +55,52 @@ void AmbientBackgroundImageView::OnGestureEvent(ui::GestureEvent* event) { ...@@ -34,6 +55,52 @@ void AmbientBackgroundImageView::OnGestureEvent(ui::GestureEvent* event) {
} }
} }
void AmbientBackgroundImageView::UpdateImage(const gfx::ImageSkia& img) {
image_view_->SetImage(img);
}
void AmbientBackgroundImageView::UpdateImageDetails(
const base::string16& details) {
details_label_->SetText(details);
}
const gfx::ImageSkia& AmbientBackgroundImageView::GetCurrentImage() {
return image_view_->GetImage();
}
gfx::Rect AmbientBackgroundImageView::GetCurrentImageBoundsForTesting() const {
return image_view_->GetImageBounds();
}
void AmbientBackgroundImageView::InitLayout() {
SetLayoutManager(std::make_unique<views::FillLayout>());
// Inits the image view. This view should have the same size of the screen.
image_view_ = AddChildView(std::make_unique<views::ImageView>());
// Inits the attribution view. It also has a full-screen size and is
// responsible for layout the details label at its bottom left corner.
views::View* attribution_view = AddChildView(std::make_unique<views::View>());
views::BoxLayout* attribution_layout =
attribution_view->SetLayoutManager(std::make_unique<views::BoxLayout>(
views::BoxLayout::Orientation::kHorizontal));
attribution_layout->set_main_axis_alignment(
views::BoxLayout::MainAxisAlignment::kStart);
attribution_layout->set_inside_border_insets(
gfx::Insets(0, kHorizontalMarginDip, kVerticalMarginDip, 0));
// Inits the details label.
details_label_ =
attribution_view->AddChildView(std::make_unique<views::Label>());
details_label_->SetAutoColorReadabilityEnabled(false);
details_label_->SetEnabledColor(kTextColor);
details_label_->SetFontList(
ambient::util::GetDefaultFontlist().DeriveWithSizeDelta(
kDetailsFontSizeDip - kDefaultFontSizeDip));
details_label_->SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_LEFT);
details_label_->SetVerticalAlignment(gfx::VerticalAlignment::ALIGN_BOTTOM);
}
BEGIN_METADATA(AmbientBackgroundImageView) BEGIN_METADATA(AmbientBackgroundImageView)
METADATA_PARENT_CLASS(views::ImageView) METADATA_PARENT_CLASS(views::ImageView)
END_METADATA() END_METADATA()
......
...@@ -5,18 +5,25 @@ ...@@ -5,18 +5,25 @@
#ifndef ASH_AMBIENT_UI_AMBIENT_BACKGROUND_IMAGE_VIEW_H_ #ifndef ASH_AMBIENT_UI_AMBIENT_BACKGROUND_IMAGE_VIEW_H_
#define ASH_AMBIENT_UI_AMBIENT_BACKGROUND_IMAGE_VIEW_H_ #define ASH_AMBIENT_UI_AMBIENT_BACKGROUND_IMAGE_VIEW_H_
#include <string>
#include "ash/ambient/ui/ambient_view_delegate.h" #include "ash/ambient/ui/ambient_view_delegate.h"
#include "ash/ash_export.h" #include "ash/ash_export.h"
#include "ui/views/controls/image_view.h" #include "ui/views/controls/image_view.h"
#include "ui/views/metadata/metadata_header_macros.h" #include "ui/views/metadata/metadata_header_macros.h"
#include "ui/views/view.h" #include "ui/views/view.h"
namespace views {
class Label;
} // namespace views
namespace ash { namespace ash {
// AmbientBackgroundImageView-------------------------------------------------- // AmbientBackgroundImageView--------------------------------------------------
// A custom ImageView for ambient mode to handle specific mouse/gesture events // A custom ImageView to display photo image and details information on ambient.
// when the user interacts with the background photos. // It also handles specific mouse/gesture events to dismiss ambient when user
class ASH_EXPORT AmbientBackgroundImageView : public views::ImageView { // interacts with the background photos.
class ASH_EXPORT AmbientBackgroundImageView : public views::View {
public: public:
METADATA_HEADER(AmbientBackgroundImageView); METADATA_HEADER(AmbientBackgroundImageView);
...@@ -29,9 +36,28 @@ class ASH_EXPORT AmbientBackgroundImageView : public views::ImageView { ...@@ -29,9 +36,28 @@ class ASH_EXPORT AmbientBackgroundImageView : public views::ImageView {
bool OnMousePressed(const ui::MouseEvent& event) override; bool OnMousePressed(const ui::MouseEvent& event) override;
void OnGestureEvent(ui::GestureEvent* event) override; void OnGestureEvent(ui::GestureEvent* event) override;
// Updates the display image.
void UpdateImage(const gfx::ImageSkia& img);
// Updates the details for the currently displayed image.
void UpdateImageDetails(const base::string16& details);
const gfx::ImageSkia& GetCurrentImage();
gfx::Rect GetCurrentImageBoundsForTesting() const;
private: private:
void InitLayout();
// Owned by |AmbientController| and should always outlive |this|. // Owned by |AmbientController| and should always outlive |this|.
AmbientViewDelegate* delegate_ = nullptr; AmbientViewDelegate* delegate_ = nullptr;
// View to display the current image on ambient. Owned by the view hierarchy.
views::ImageView* image_view_ = nullptr;
// Label to show details text, i.e. attribution, to be displayed for the
// current image. Owned by the view hierarchy.
views::Label* details_label_ = nullptr;
}; };
} // namespace ash } // namespace ash
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "ash/ambient/ui/photo_view.h" #include "ash/ambient/ui/photo_view.h"
#include <algorithm> #include <algorithm>
#include <iterator>
#include <memory> #include <memory>
#include "ash/ambient/ambient_constants.h" #include "ash/ambient/ambient_constants.h"
...@@ -14,6 +15,7 @@ ...@@ -14,6 +15,7 @@
#include "ash/assistant/ui/assistant_view_ids.h" #include "ash/assistant/ui/assistant_view_ids.h"
#include "ash/public/cpp/metrics_util.h" #include "ash/public/cpp/metrics_util.h"
#include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_functions.h"
#include "base/strings/utf_string_conversions.h"
#include "ui/aura/window.h" #include "ui/aura/window.h"
#include "ui/compositor/animation_metrics_reporter.h" #include "ui/compositor/animation_metrics_reporter.h"
#include "ui/compositor/animation_throughput_reporter.h" #include "ui/compositor/animation_throughput_reporter.h"
...@@ -82,7 +84,7 @@ void PhotoView::OnBoundsChanged(const gfx::Rect& previous_bounds) { ...@@ -82,7 +84,7 @@ void PhotoView::OnBoundsChanged(const gfx::Rect& previous_bounds) {
for (const int index : {0, 1}) { for (const int index : {0, 1}) {
auto image = images_unscaled_[index]; auto image = images_unscaled_[index];
auto image_resized = ResizeImage(image, size()); auto image_resized = ResizeImage(image, size());
image_views_[index]->SetImage(image_resized); image_views_[index]->UpdateImage(image_resized);
} }
} }
...@@ -103,14 +105,16 @@ void PhotoView::Init() { ...@@ -103,14 +105,16 @@ void PhotoView::Init() {
layer()->SetFillsBoundsOpaquely(false); layer()->SetFillsBoundsOpaquely(false);
SetLayoutManager(std::make_unique<views::FillLayout>()); SetLayoutManager(std::make_unique<views::FillLayout>());
image_views_[0] = for (auto*& image_view : image_views_) {
AddChildView(std::make_unique<AmbientBackgroundImageView>(delegate_)); // Creates image views.
image_views_[1] = image_view =
AddChildView(std::make_unique<AmbientBackgroundImageView>(delegate_)); AddChildView(std::make_unique<AmbientBackgroundImageView>(delegate_));
image_views_[0]->SetPaintToLayer(); // Each image view will be animated on its own layer.
image_views_[0]->layer()->SetFillsBoundsOpaquely(false); image_view->SetPaintToLayer();
image_views_[1]->SetPaintToLayer(); image_view->layer()->SetFillsBoundsOpaquely(false);
image_views_[1]->layer()->SetFillsBoundsOpaquely(false); }
// Hides one image view initially for fade in animation.
image_views_[1]->layer()->SetOpacity(0.0f); image_views_[1]->layer()->SetOpacity(0.0f);
delegate_->GetAmbientBackendModel()->AddObserver(this); delegate_->GetAmbientBackendModel()->AddObserver(this);
...@@ -118,12 +122,15 @@ void PhotoView::Init() { ...@@ -118,12 +122,15 @@ void PhotoView::Init() {
void PhotoView::UpdateImages() { void PhotoView::UpdateImages() {
auto* model = delegate_->GetAmbientBackendModel(); auto* model = delegate_->GetAmbientBackendModel();
images_unscaled_[image_index_] = model->GetNextImage().photo; auto& next_image = model->GetNextImage();
images_unscaled_[image_index_] = next_image.photo;
if (images_unscaled_[image_index_].isNull()) if (images_unscaled_[image_index_].isNull())
return; return;
auto next_resized = ResizeImage(images_unscaled_[image_index_], size()); auto next_resized = ResizeImage(images_unscaled_[image_index_], size());
image_views_[image_index_]->SetImage(next_resized); image_views_[image_index_]->UpdateImage(next_resized);
image_views_[image_index_]->UpdateImageDetails(
base::UTF8ToUTF16(next_image.details));
image_index_ = 1 - image_index_; image_index_ = 1 - image_index_;
} }
...@@ -175,7 +182,7 @@ bool PhotoView::NeedToAnimateTransition() const { ...@@ -175,7 +182,7 @@ bool PhotoView::NeedToAnimateTransition() const {
} }
const gfx::ImageSkia& PhotoView::GetCurrentImagesForTesting() { const gfx::ImageSkia& PhotoView::GetCurrentImagesForTesting() {
return image_views_[image_index_]->GetImage(); return image_views_[image_index_]->GetCurrentImage();
} }
} // namespace ash } // namespace ash
...@@ -32,7 +32,7 @@ TEST_F(AmbientPhotoViewTest, ShouldResizePortraitImageForPortraitScreen) { ...@@ -32,7 +32,7 @@ TEST_F(AmbientPhotoViewTest, ShouldResizePortraitImageForPortraitScreen) {
// Image should be full width. Image height should extend above and below the // Image should be full width. Image height should extend above and below the
// visible part of the screen. // visible part of the screen.
ASSERT_EQ(image_view->GetImageBounds(), ASSERT_EQ(image_view->GetCurrentImageBoundsForTesting(),
gfx::Rect(/*x=*/0, /*y=*/-200, /*width=*/600, /*height=*/1200)); gfx::Rect(/*x=*/0, /*y=*/-200, /*width=*/600, /*height=*/1200));
} }
...@@ -52,7 +52,7 @@ TEST_F(AmbientPhotoViewTest, ShouldResizeLandscapeImageForPortraitScreen) { ...@@ -52,7 +52,7 @@ TEST_F(AmbientPhotoViewTest, ShouldResizeLandscapeImageForPortraitScreen) {
// Image should be full width. Image should have equal empty space top and // Image should be full width. Image should have equal empty space top and
// bottom. // bottom.
ASSERT_EQ(image_view->GetImageBounds(), ASSERT_EQ(image_view->GetCurrentImageBoundsForTesting(),
gfx::Rect(/*x=*/0, /*y=*/200, /*width=*/600, /*height=*/400)); gfx::Rect(/*x=*/0, /*y=*/200, /*width=*/600, /*height=*/400));
} }
...@@ -72,7 +72,7 @@ TEST_F(AmbientPhotoViewTest, ShouldResizePortraitImageForLandscapeScreen) { ...@@ -72,7 +72,7 @@ TEST_F(AmbientPhotoViewTest, ShouldResizePortraitImageForLandscapeScreen) {
// Image should be full height. Image width should have equal empty space on // Image should be full height. Image width should have equal empty space on
// left and right. // left and right.
ASSERT_EQ(image_view->GetImageBounds(), ASSERT_EQ(image_view->GetCurrentImageBoundsForTesting(),
gfx::Rect(/*x=*/250, /*y=*/0, /*width=*/300, /*height=*/600)); gfx::Rect(/*x=*/250, /*y=*/0, /*width=*/300, /*height=*/600));
} }
...@@ -93,7 +93,7 @@ TEST_F(AmbientPhotoViewTest, ShouldResizeLandscapeImageForFillLandscapeScreen) { ...@@ -93,7 +93,7 @@ TEST_F(AmbientPhotoViewTest, ShouldResizeLandscapeImageForFillLandscapeScreen) {
// Image should be full height. Image width should extend equally to the left // Image should be full height. Image width should extend equally to the left
// and right of the visible part of the screen. // and right of the visible part of the screen.
ASSERT_EQ(image_view->GetImageBounds(), ASSERT_EQ(image_view->GetCurrentImageBoundsForTesting(),
gfx::Rect(/*x=*/-50, /*y=*/0, /*width=*/900, /*height=*/600)); gfx::Rect(/*x=*/-50, /*y=*/0, /*width=*/900, /*height=*/600));
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment