Commit 50dc3f49 authored by David Black's avatar David Black Committed by Commit Bot

Refactor AnimatedContainerView for response processing v2.

This CL modifies AnimatedContainerView to:
- Split HandleResponse() into HandleSuggestion() and HandleUiElement().
- In this CL, these new functions are invoked at the same time as
  HandleResponse(), but a follow up CL will add additional invocations
  in response processing v2 in reaction to AssistantResponseObserver
  events.
- Modifies existing paradigm of derivative classes explicitly having to
  call AddElementAnimator() to instead have HandleSuggestion() and
  HandleUiElement() return any new animators that should be owned and
  acted upon. This will be convenient in response processing v2 when
  animations are most often *not* performed in unison.

Other changes in this CL are trivial and should be straightforward to
follow :)

Note that this CL has *no effect* on existing behavior.


Bug: b:129411551
Change-Id: Ibbcd7654c5a2b6dfe7ca488dc559738531085b09
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2067473
Commit-Queue: David Black <dmblack@google.com>
Reviewed-by: default avatarXiaohui Chen <xiaohuic@chromium.org>
Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Reviewed-by: default avatarJeroen Dhollander <jeroendh@google.com>
Cr-Commit-Position: refs/heads/master@{#745742}
parent 7dbbad30
...@@ -4,8 +4,6 @@ ...@@ -4,8 +4,6 @@
#include "ash/ambient/ui/assistant_response_container_view.h" #include "ash/ambient/ui/assistant_response_container_view.h"
#include <memory>
#include "ash/assistant/model/assistant_interaction_model_observer.h" #include "ash/assistant/model/assistant_interaction_model_observer.h"
#include "ash/assistant/model/assistant_response.h" #include "ash/assistant/model/assistant_response.h"
#include "ash/assistant/model/ui/assistant_card_element.h" #include "ash/assistant/model/ui/assistant_card_element.h"
...@@ -13,6 +11,7 @@ ...@@ -13,6 +11,7 @@
#include "ash/assistant/model/ui/assistant_ui_element.h" #include "ash/assistant/model/ui/assistant_ui_element.h"
#include "ash/assistant/ui/assistant_view_delegate.h" #include "ash/assistant/ui/assistant_view_delegate.h"
#include "ash/assistant/ui/main_stage/assistant_text_element_view.h" #include "ash/assistant/ui/main_stage/assistant_text_element_view.h"
#include "ash/assistant/ui/main_stage/element_animator.h"
#include "ui/views/layout/box_layout.h" #include "ui/views/layout/box_layout.h"
namespace ash { namespace ash {
...@@ -51,23 +50,23 @@ void AssistantResponseContainerView::InitLayout() { ...@@ -51,23 +50,23 @@ void AssistantResponseContainerView::InitLayout() {
views::BoxLayout::Orientation::kVertical)); views::BoxLayout::Orientation::kVertical));
} }
void AssistantResponseContainerView::HandleResponse( std::unique_ptr<ElementAnimator>
const AssistantResponse& response) { AssistantResponseContainerView::HandleUiElement(
for (const auto& ui_element : response.GetUiElements()) { const AssistantUiElement* ui_element) {
switch (ui_element->type()) { switch (ui_element->type()) {
case AssistantUiElementType::kCard: case AssistantUiElementType::kCard:
// For card elements, we instead use the "fallback" message for HTML // For card elements, we instead use the "fallback" message for HTML
// card rendering as the text response. // card rendering as the text response.
AddTextElementView(new AssistantTextElement( AddTextElementView(new AssistantTextElement(
static_cast<const AssistantCardElement*>(ui_element.get()) static_cast<const AssistantCardElement*>(ui_element)->fallback()));
->fallback()));
break; break;
case AssistantUiElementType::kText: case AssistantUiElementType::kText:
AddTextElementView( AddTextElementView(static_cast<const AssistantTextElement*>(ui_element));
static_cast<const AssistantTextElement*>(ui_element.get()));
break; break;
} }
}
// Return |nullptr| to prevent animations.
return nullptr;
} }
void AssistantResponseContainerView::AddTextElementView( void AssistantResponseContainerView::AddTextElementView(
......
...@@ -5,12 +5,13 @@ ...@@ -5,12 +5,13 @@
#ifndef ASH_AMBIENT_UI_ASSISTANT_RESPONSE_CONTAINER_VIEW_H_ #ifndef ASH_AMBIENT_UI_ASSISTANT_RESPONSE_CONTAINER_VIEW_H_
#define ASH_AMBIENT_UI_ASSISTANT_RESPONSE_CONTAINER_VIEW_H_ #define ASH_AMBIENT_UI_ASSISTANT_RESPONSE_CONTAINER_VIEW_H_
#include <memory>
#include "ash/assistant/ui/main_stage/animated_container_view.h" #include "ash/assistant/ui/main_stage/animated_container_view.h"
#include "base/macros.h" #include "base/macros.h"
namespace ash { namespace ash {
class AssistantResponse;
class AssistantTextElement; class AssistantTextElement;
class AssistantViewDelegate; class AssistantViewDelegate;
...@@ -29,7 +30,8 @@ class AssistantResponseContainerView : public AnimatedContainerView { ...@@ -29,7 +30,8 @@ class AssistantResponseContainerView : public AnimatedContainerView {
void AddTextElementView(const AssistantTextElement* text_element); void AddTextElementView(const AssistantTextElement* text_element);
// AnimatedContainerView: // AnimatedContainerView:
void HandleResponse(const AssistantResponse& response) override; std::unique_ptr<ElementAnimator> HandleUiElement(
const AssistantUiElement* ui_element) override;
DISALLOW_COPY_AND_ASSIGN(AssistantResponseContainerView); DISALLOW_COPY_AND_ASSIGN(AssistantResponseContainerView);
}; };
......
...@@ -386,6 +386,14 @@ void AssistantInteractionController::OnInteractionStarted( ...@@ -386,6 +386,14 @@ void AssistantInteractionController::OnInteractionStarted(
void AssistantInteractionController::OnInteractionFinished( void AssistantInteractionController::OnInteractionFinished(
AssistantInteractionResolution resolution) { AssistantInteractionResolution resolution) {
// If we don't have an active interaction, that indicates that this
// interaction was explicitly stopped outside of LibAssistant. In this case,
// we ensure that the mic is closed but otherwise ignore this event.
if (IsResponseProcessingV2Enabled() && !HasActiveInteraction()) {
model_.SetMicState(MicState::kClosed);
return;
}
model_.SetInteractionState(InteractionState::kInactive); model_.SetInteractionState(InteractionState::kInactive);
model_.SetMicState(MicState::kClosed); model_.SetMicState(MicState::kClosed);
......
...@@ -165,18 +165,22 @@ AssistantResponse::GetUiElements() const { ...@@ -165,18 +165,22 @@ AssistantResponse::GetUiElements() const {
return ui_elements_; return ui_elements_;
} }
// TODO(b/112034793): Migrate |id| into AssistantSuggestion.
void AssistantResponse::AddSuggestions( void AssistantResponse::AddSuggestions(
std::vector<AssistantSuggestionPtr> suggestions) { std::vector<AssistantSuggestionPtr> suggestions) {
std::vector<AssistantSuggestion*> ptrs; // A mapping of raw suggestion pointers to their respective ids. Note that we
// use the index of each suggestion within our backing vector to represent id.
std::map<int, const AssistantSuggestion*> ptrs;
for (AssistantSuggestionPtr& suggestion : suggestions) { for (AssistantSuggestionPtr& suggestion : suggestions) {
suggestions_.push_back(std::move(suggestion)); suggestions_.push_back(std::move(suggestion));
ptrs.push_back(suggestions_.back().get()); ptrs.insert({suggestions_.size() - 1, suggestions_.back().get()});
} }
NotifySuggestionsAdded(ptrs); NotifySuggestionsAdded(ptrs);
} }
// TODO(b/112034793): Migrate |id| into AssistantSuggestion.
const chromeos::assistant::mojom::AssistantSuggestion* const chromeos::assistant::mojom::AssistantSuggestion*
AssistantResponse::GetSuggestionById(int id) const { AssistantResponse::GetSuggestionById(int id) const {
// We consider the index of a suggestion within our backing vector to be its // We consider the index of a suggestion within our backing vector to be its
...@@ -186,12 +190,13 @@ AssistantResponse::GetSuggestionById(int id) const { ...@@ -186,12 +190,13 @@ AssistantResponse::GetSuggestionById(int id) const {
return suggestions_.at(id).get(); return suggestions_.at(id).get();
} }
// TODO(b/112034793): Migrate |id| into AssistantSuggestion.
std::map<int, const chromeos::assistant::mojom::AssistantSuggestion*> std::map<int, const chromeos::assistant::mojom::AssistantSuggestion*>
AssistantResponse::GetSuggestions() const { AssistantResponse::GetSuggestions() const {
// A mapping of raw suggestion pointers to their respective ids. Note that we
// use the index of each suggestion within our backing vector to represent id.
std::map<int, const AssistantSuggestion*> suggestions; std::map<int, const AssistantSuggestion*> suggestions;
// We use index within our backing vector to represent the unique identifier
// for a suggestion.
int id = 0; int id = 0;
for (const AssistantSuggestionPtr& suggestion : suggestions_) for (const AssistantSuggestionPtr& suggestion : suggestions_)
suggestions[id++] = suggestion.get(); suggestions[id++] = suggestion.get();
...@@ -211,7 +216,7 @@ void AssistantResponse::NotifyUiElementAdded( ...@@ -211,7 +216,7 @@ void AssistantResponse::NotifyUiElementAdded(
} }
void AssistantResponse::NotifySuggestionsAdded( void AssistantResponse::NotifySuggestionsAdded(
const std::vector<AssistantSuggestion*>& suggestions) { const std::map<int, const AssistantSuggestion*>& suggestions) {
for (auto& observer : observers_) for (auto& observer : observers_)
observer.OnSuggestionsAdded(suggestions); observer.OnSuggestionsAdded(suggestions);
} }
......
...@@ -82,7 +82,7 @@ class COMPONENT_EXPORT(ASSISTANT_MODEL) AssistantResponse ...@@ -82,7 +82,7 @@ class COMPONENT_EXPORT(ASSISTANT_MODEL) AssistantResponse
private: private:
void NotifyUiElementAdded(const AssistantUiElement* ui_element); void NotifyUiElementAdded(const AssistantUiElement* ui_element);
void NotifySuggestionsAdded(const std::vector<AssistantSuggestion*>&); void NotifySuggestionsAdded(const std::map<int, const AssistantSuggestion*>&);
struct PendingUiElement; struct PendingUiElement;
class Processor; class Processor;
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
#ifndef ASH_ASSISTANT_MODEL_ASSISTANT_RESPONSE_OBSERVER_H_ #ifndef ASH_ASSISTANT_MODEL_ASSISTANT_RESPONSE_OBSERVER_H_
#define ASH_ASSISTANT_MODEL_ASSISTANT_RESPONSE_OBSERVER_H_ #define ASH_ASSISTANT_MODEL_ASSISTANT_RESPONSE_OBSERVER_H_
#include <vector> #include <map>
#include "base/component_export.h" #include "base/component_export.h"
#include "base/observer_list_types.h" #include "base/observer_list_types.h"
...@@ -25,7 +25,9 @@ class COMPONENT_EXPORT(ASSISTANT_MODEL) AssistantResponseObserver ...@@ -25,7 +25,9 @@ class COMPONENT_EXPORT(ASSISTANT_MODEL) AssistantResponseObserver
virtual void OnUiElementAdded(const AssistantUiElement* ui_element) {} virtual void OnUiElementAdded(const AssistantUiElement* ui_element) {}
// Invoked when the specified |suggestions| are added to the response. // Invoked when the specified |suggestions| are added to the response.
virtual void OnSuggestionsAdded(const std::vector<AssistantSuggestion*>&) {} // Note that the provided map is keyed by id.
virtual void OnSuggestionsAdded(
const std::map<int, const AssistantSuggestion*>& suggestions) {}
protected: protected:
AssistantResponseObserver() = default; AssistantResponseObserver() = default;
......
...@@ -101,6 +101,17 @@ void AnimatedContainerView::AnimateIn() { ...@@ -101,6 +101,17 @@ void AnimatedContainerView::AnimateIn() {
animation_observer->SetActive(); animation_observer->SetActive();
} }
std::unique_ptr<ElementAnimator> AnimatedContainerView::HandleUiElement(
const AssistantUiElement* ui_element) {
return nullptr;
}
std::unique_ptr<ElementAnimator> AnimatedContainerView::HandleSuggestion(
int id,
const AssistantSuggestion* suggestion) {
return nullptr;
}
void AnimatedContainerView::SetPropagatePreferredSizeChanged(bool propagate) { void AnimatedContainerView::SetPropagatePreferredSizeChanged(bool propagate) {
if (propagate == propagate_preferred_size_changed_) if (propagate == propagate_preferred_size_changed_)
return; return;
...@@ -189,7 +200,25 @@ void AnimatedContainerView::AddResponse( ...@@ -189,7 +200,25 @@ void AnimatedContainerView::AddResponse(
// to the view hierarchy to reduce layout passes. // to the view hierarchy to reduce layout passes.
SetPropagatePreferredSizeChanged(false); SetPropagatePreferredSizeChanged(false);
HandleResponse(*response_); std::vector<std::unique_ptr<ElementAnimator>> animators;
// Create views (and animators) for the suggestions belonging to the response.
for (const auto& pair : response_->GetSuggestions()) {
auto animator =
HandleSuggestion(/*id=*/pair.first, /*suggestion=*/pair.second);
if (animator)
animators.push_back(std::move(animator));
}
// Create views (and animators) for the UI elements belonging to the response.
for (const auto& ui_element : response_->GetUiElements()) {
auto animator = HandleUiElement(ui_element.get());
if (animator)
animators.push_back(std::move(animator));
}
// Cache the animators that were just created.
std::move(animators.begin(), animators.end(), std::back_inserter(animators_));
// Now that the response for the current query has been added to the view // Now that the response for the current query has been added to the view
// hierarchy, we can restart propagation of PreferredSizeChanged events since // hierarchy, we can restart propagation of PreferredSizeChanged events since
......
...@@ -5,11 +5,13 @@ ...@@ -5,11 +5,13 @@
#ifndef ASH_ASSISTANT_UI_MAIN_STAGE_ANIMATED_CONTAINER_VIEW_H_ #ifndef ASH_ASSISTANT_UI_MAIN_STAGE_ANIMATED_CONTAINER_VIEW_H_
#define ASH_ASSISTANT_UI_MAIN_STAGE_ANIMATED_CONTAINER_VIEW_H_ #define ASH_ASSISTANT_UI_MAIN_STAGE_ANIMATED_CONTAINER_VIEW_H_
#include <map>
#include <memory> #include <memory>
#include <vector> #include <vector>
#include "ash/assistant/model/assistant_interaction_model_observer.h" #include "ash/assistant/model/assistant_interaction_model_observer.h"
#include "ash/assistant/ui/base/assistant_scroll_view.h" #include "ash/assistant/ui/base/assistant_scroll_view.h"
#include "chromeos/services/assistant/public/mojom/assistant.mojom-forward.h"
namespace ui { namespace ui {
class CallbackLayerAnimationObserver; class CallbackLayerAnimationObserver;
...@@ -17,40 +19,43 @@ class CallbackLayerAnimationObserver; ...@@ -17,40 +19,43 @@ class CallbackLayerAnimationObserver;
namespace ash { namespace ash {
class AssistantViewDelegate;
class AssistantResponse; class AssistantResponse;
class AssistantUiElement;
class AssistantViewDelegate;
class ElementAnimator; class ElementAnimator;
// A view that will observe the |AssistantResponse| and which will use // A view that will observe the AssistantResponse and which will use
// |ElementAnimator| to animate each child view. // ElementAnimator to animate each child view.
// //
// To use this you must implement |HandleResponse| and in there // To use this you should implement HandleUiElement() and/or HandleSuggestion()
// - Add the new child views for the given |AssistantResponse|. // to:
// - Add animators for the new view by calling |AddElementAnimator|. // - Add new child views as appropriate.
// - Return animators for any newly created views.
// //
// More in detail, this is what will happen: // More in detail, this is what will happen:
// 1) When |AssistantInteractionModelObserver::OnCommittedQueryChanged| is // 1) When AssistantInteractionModelObserver::OnCommittedQueryChanged() is
// observed, |FadeOut| is called on all |ElementAnimator| instances. // observed, FadeOut() is called on all ElementAnimator instances.
// Furthermore all views will stop processing events (like click). // Furthermore all views will stop processing events (like click).
// 2) When |AssistantInteractionModelObserver::OnResponseChanged| is // 2) When AssistantInteractionModelObserver::OnResponseChanged() is
// observed, we wait until the |FadeOut| animations are complete. // observed, we wait until the FadeOut() animations are complete.
// 3) Next |AnimateOut| is invoked on all |ElementAnimator| instances. // 3) Next AnimateOut() is invoked on all ElementAnimator instances.
// 4) When these animations are complete, all child views are removed. // 4) When these animations are complete, all child views are removed.
// 5) |AnimatedContainerView::OnAllViewsRemoved| is invoked to inform // 5) OnAllViewsRemoved() is invoked to inform the derived class all child
// the derived class all child views are removed. // views are removed.
// 6) Next |AnimatedContainerView::HandleResponse| is called with the new // 6) Next HandleSuggestion() and HandleUiElement() is called for the new
// |AssistantResponse|. // AssistantResponse. In those methods, the derived class should add the
// In here the derived class should add the child views for the new // child views for the new response, as well as return ElementAnimator
// response, as well as adding |ElementAnimator| instances by calling // instances.
// |AnimatedContainerView::AddElementAnimator|. // 7) When all new child views have been added, AnimateIn() is invoked on
// 7) When all new child views have been added, |AnimateIn| is invoked on // all ElementAnimator instances.
// all |ElementAnimator| instances.
// 8) Finally when this animation is complete the derived class is informed // 8) Finally when this animation is complete the derived class is informed
// through |AnimatedContainerView::OnAllViewsAnimatedIn|. // through OnAllViewsAnimatedIn().
class COMPONENT_EXPORT(ASSISTANT_UI) AnimatedContainerView class COMPONENT_EXPORT(ASSISTANT_UI) AnimatedContainerView
: public AssistantScrollView, : public AssistantScrollView,
public AssistantInteractionModelObserver { public AssistantInteractionModelObserver {
public: public:
using AssistantSuggestion = chromeos::assistant::mojom::AssistantSuggestion;
explicit AnimatedContainerView(AssistantViewDelegate* delegate); explicit AnimatedContainerView(AssistantViewDelegate* delegate);
~AnimatedContainerView() override; ~AnimatedContainerView() override;
...@@ -65,8 +70,7 @@ class COMPONENT_EXPORT(ASSISTANT_UI) AnimatedContainerView ...@@ -65,8 +70,7 @@ class COMPONENT_EXPORT(ASSISTANT_UI) AnimatedContainerView
// AssistantInteractionModelObserver: // AssistantInteractionModelObserver:
void OnCommittedQueryChanged(const AssistantQuery& query) override; void OnCommittedQueryChanged(const AssistantQuery& query) override;
void OnResponseChanged( void OnResponseChanged(const scoped_refptr<AssistantResponse>&) override;
const scoped_refptr<AssistantResponse>& response) override;
void OnResponseCleared() override; void OnResponseCleared() override;
// Remove all current responses/views. // Remove all current responses/views.
...@@ -88,12 +92,22 @@ class COMPONENT_EXPORT(ASSISTANT_UI) AnimatedContainerView ...@@ -88,12 +92,22 @@ class COMPONENT_EXPORT(ASSISTANT_UI) AnimatedContainerView
// This is called when the exit animations are done. // This is called when the exit animations are done.
virtual void OnAllViewsRemoved() {} virtual void OnAllViewsRemoved() {}
// Callback called to create the new views. // Callback called to create a view for a UI element.
// For each new views it should // The implementer should:
// - Create and add the |views::View|. // - Create and add the appropriate views::View.
// - Call |AddElementAnimator| and pass it the |ElementAnimator| to // - Return an ElementAnimator to animate the view. Note that it is
// animate the view. // permissible to return |nullptr| if no managed animation is desired.
virtual void HandleResponse(const AssistantResponse& response) = 0; virtual std::unique_ptr<ElementAnimator> HandleUiElement(
const AssistantUiElement* ui_element);
// Callback called to create a view for a suggestion.
// The implementer should:
// - Create and add the appropriate views::View.
// - Return an ElementAnimator to animate the view. Note that it is
// permissible to return |nullptr| if no managed animation is desired.
virtual std::unique_ptr<ElementAnimator> HandleSuggestion(
int id,
const AssistantSuggestion* suggestion);
AssistantViewDelegate* delegate() { return delegate_; } AssistantViewDelegate* delegate() { return delegate_; }
......
...@@ -21,14 +21,14 @@ AssistantUiElementViewFactory::AssistantUiElementViewFactory( ...@@ -21,14 +21,14 @@ AssistantUiElementViewFactory::AssistantUiElementViewFactory(
AssistantUiElementViewFactory::~AssistantUiElementViewFactory() = default; AssistantUiElementViewFactory::~AssistantUiElementViewFactory() = default;
std::unique_ptr<AssistantUiElementView> AssistantUiElementViewFactory::Create( std::unique_ptr<AssistantUiElementView> AssistantUiElementViewFactory::Create(
AssistantUiElement* ui_element) const { const AssistantUiElement* ui_element) const {
switch (ui_element->type()) { switch (ui_element->type()) {
case AssistantUiElementType::kCard: case AssistantUiElementType::kCard:
return std::make_unique<AssistantCardElementView>( return std::make_unique<AssistantCardElementView>(
delegate_, static_cast<AssistantCardElement*>(ui_element)); delegate_, static_cast<const AssistantCardElement*>(ui_element));
case AssistantUiElementType::kText: case AssistantUiElementType::kText:
return std::make_unique<AssistantTextElementView>( return std::make_unique<AssistantTextElementView>(
static_cast<AssistantTextElement*>(ui_element)); static_cast<const AssistantTextElement*>(ui_element));
} }
} }
......
...@@ -26,7 +26,7 @@ class COMPONENT_EXPORT(ASSISTANT_UI) AssistantUiElementViewFactory { ...@@ -26,7 +26,7 @@ class COMPONENT_EXPORT(ASSISTANT_UI) AssistantUiElementViewFactory {
// Creates a view for the specified |ui_element|. // Creates a view for the specified |ui_element|.
std::unique_ptr<AssistantUiElementView> Create( std::unique_ptr<AssistantUiElementView> Create(
AssistantUiElement* ui_element) const; const AssistantUiElement* ui_element) const;
private: private:
// Owned by AssistantController. // Owned by AssistantController.
......
...@@ -183,19 +183,28 @@ void SuggestionContainerView::OnConversationStartersChanged( ...@@ -183,19 +183,28 @@ void SuggestionContainerView::OnConversationStartersChanged(
return; return;
RemoveAllViews(); RemoveAllViews();
OnSuggestionsChanged(conversation_starters);
std::vector<std::unique_ptr<ElementAnimator>> animators;
for (const auto& pair : conversation_starters) {
auto animator =
AddSuggestionChip(/*id=*/pair.first, /*suggestion=*/pair.second);
if (animator)
AddElementAnimator(std::move(animator));
}
AnimateIn(); AnimateIn();
} }
void SuggestionContainerView::HandleResponse( std::unique_ptr<ElementAnimator> SuggestionContainerView::HandleSuggestion(
const AssistantResponse& response) { int id,
const AssistantSuggestion* suggestion) {
has_received_response_ = true; has_received_response_ = true;
// When no longer showing conversation starters, we start align our content. // When no longer showing conversation starters, we start align our content.
layout_manager_->set_main_axis_alignment( layout_manager_->set_main_axis_alignment(
views::BoxLayout::MainAxisAlignment::kStart); views::BoxLayout::MainAxisAlignment::kStart);
OnSuggestionsChanged(response.GetSuggestions()); return AddSuggestionChip(id, suggestion);
} }
void SuggestionContainerView::OnAllViewsRemoved() { void SuggestionContainerView::OnAllViewsRemoved() {
...@@ -213,28 +222,17 @@ void SuggestionContainerView::OnAllViewsRemoved() { ...@@ -213,28 +222,17 @@ void SuggestionContainerView::OnAllViewsRemoved() {
// not whether we are currently displaying a response. // not whether we are currently displaying a response.
} }
void SuggestionContainerView::OnSuggestionsChanged( std::unique_ptr<ElementAnimator> SuggestionContainerView::AddSuggestionChip(
const std::map<int, const AssistantSuggestion*>& suggestions) { int id,
for (const auto& suggestion : suggestions) { const AssistantSuggestion* suggestion) {
// We will use the same identifier by which the Assistant interaction model
// uniquely identifies a suggestion to uniquely identify its corresponding
// suggestion chip view.
AddSuggestionChip(/*suggestion=*/*suggestion.second,
/*id=*/suggestion.first);
}
}
void SuggestionContainerView::AddSuggestionChip(
const AssistantSuggestion& suggestion,
int id) {
SuggestionChipView::Params params; SuggestionChipView::Params params;
params.text = base::UTF8ToUTF16(suggestion.text); params.text = base::UTF8ToUTF16(suggestion->text);
if (!suggestion.icon_url.is_empty()) { if (!suggestion->icon_url.is_empty()) {
// Initiate a request to download the image for the suggestion chip icon. // Initiate a request to download the image for the suggestion chip icon.
// Note that the request is identified by the suggestion id. // Note that the request is identified by the suggestion id.
delegate()->DownloadImage( delegate()->DownloadImage(
suggestion.icon_url, suggestion->icon_url,
base::BindOnce(&SuggestionContainerView::OnSuggestionChipIconDownloaded, base::BindOnce(&SuggestionContainerView::OnSuggestionChipIconDownloaded,
download_request_weak_factory_.GetWeakPtr(), id)); download_request_weak_factory_.GetWeakPtr(), id));
...@@ -261,9 +259,9 @@ void SuggestionContainerView::AddSuggestionChip( ...@@ -261,9 +259,9 @@ void SuggestionContainerView::AddSuggestionChip(
suggestion_chip_views_[id] = suggestion_chip_views_[id] =
content_view()->AddChildView(std::move(suggestion_chip_view)); content_view()->AddChildView(std::move(suggestion_chip_view));
// Set the animations for the suggestion chip. // Return the animator for the suggestion chip.
AddElementAnimator(std::make_unique<SuggestionChipAnimator>( return std::make_unique<SuggestionChipAnimator>(suggestion_chip_views_[id],
suggestion_chip_views_[id], this)); this);
} }
void SuggestionContainerView::OnSuggestionChipIconDownloaded( void SuggestionContainerView::OnSuggestionChipIconDownloaded(
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <map> #include <map>
#include <memory> #include <memory>
#include <vector>
#include "ash/assistant/model/assistant_suggestions_model_observer.h" #include "ash/assistant/model/assistant_suggestions_model_observer.h"
#include "ash/assistant/model/assistant_ui_model_observer.h" #include "ash/assistant/model/assistant_ui_model_observer.h"
...@@ -71,12 +72,14 @@ class COMPONENT_EXPORT(ASSISTANT_UI) SuggestionContainerView ...@@ -71,12 +72,14 @@ class COMPONENT_EXPORT(ASSISTANT_UI) SuggestionContainerView
void InitLayout(); void InitLayout();
// AnimatedContainerView: // AnimatedContainerView:
void HandleResponse(const AssistantResponse& response) override; std::unique_ptr<ElementAnimator> HandleSuggestion(
int id,
const AssistantSuggestion* suggestion) override;
void OnAllViewsRemoved() override; void OnAllViewsRemoved() override;
void OnSuggestionsChanged( std::unique_ptr<ElementAnimator> AddSuggestionChip(
const std::map<int, const AssistantSuggestion*>& suggestions); int id,
void AddSuggestionChip(const AssistantSuggestion& suggestion, int id); const AssistantSuggestion* suggestion);
// Invoked on suggestion chip icon downloaded event. // Invoked on suggestion chip icon downloaded event.
void OnSuggestionChipIconDownloaded(int id, const gfx::ImageSkia& icon); void OnSuggestionChipIconDownloaded(int id, const gfx::ImageSkia& icon);
......
...@@ -121,10 +121,10 @@ void UiElementContainerView::OnCommittedQueryChanged( ...@@ -121,10 +121,10 @@ void UiElementContainerView::OnCommittedQueryChanged(
AnimatedContainerView::OnCommittedQueryChanged(query); AnimatedContainerView::OnCommittedQueryChanged(query);
} }
void UiElementContainerView::HandleResponse(const AssistantResponse& response) { std::unique_ptr<ElementAnimator> UiElementContainerView::HandleUiElement(
for (const auto& ui_element : response.GetUiElements()) { const AssistantUiElement* ui_element) {
// Create a new view for the |ui_element|. // Create a new view for the |ui_element|.
auto view = view_factory_->Create(ui_element.get()); auto view = view_factory_->Create(ui_element);
// If the first UI element is a card, it has a unique margin requirement. // If the first UI element is a card, it has a unique margin requirement.
const bool is_card = ui_element->type() == AssistantUiElementType::kCard; const bool is_card = ui_element->type() == AssistantUiElementType::kCard;
...@@ -134,12 +134,12 @@ void UiElementContainerView::HandleResponse(const AssistantResponse& response) { ...@@ -134,12 +134,12 @@ void UiElementContainerView::HandleResponse(const AssistantResponse& response) {
view->SetBorder(views::CreateEmptyBorder(kMarginTopDip, 0, 0, 0)); view->SetBorder(views::CreateEmptyBorder(kMarginTopDip, 0, 0, 0));
} }
// Add the view to the view hierarchy and bind an animator to handle all of // Add the view to the hierarchy and prepare its animation layer for entry.
// its animations. Note that we prepare its animation layer for entry.
auto* view_ptr = content_view()->AddChildView(std::move(view)); auto* view_ptr = content_view()->AddChildView(std::move(view));
AddElementAnimator(view_ptr->CreateAnimator());
view_ptr->GetLayerForAnimating()->SetOpacity(0.f); view_ptr->GetLayerForAnimating()->SetOpacity(0.f);
}
// Return the animator that will be used to animate the view.
return view_ptr->CreateAnimator();
} }
void UiElementContainerView::OnAllViewsAnimatedIn() { void UiElementContainerView::OnAllViewsAnimatedIn() {
......
...@@ -18,7 +18,6 @@ ...@@ -18,7 +18,6 @@
namespace ash { namespace ash {
class AssistantResponse;
class AssistantUiElementViewFactory; class AssistantUiElementViewFactory;
class AssistantViewDelegate; class AssistantViewDelegate;
...@@ -44,7 +43,8 @@ class COMPONENT_EXPORT(ASSISTANT_UI) UiElementContainerView ...@@ -44,7 +43,8 @@ class COMPONENT_EXPORT(ASSISTANT_UI) UiElementContainerView
void InitLayout(); void InitLayout();
// AnimatedContainerView: // AnimatedContainerView:
void HandleResponse(const AssistantResponse& response) override; std::unique_ptr<ElementAnimator> HandleUiElement(
const AssistantUiElement* ui_element) override;
void OnAllViewsAnimatedIn() override; void OnAllViewsAnimatedIn() override;
void OnScrollBarUpdated(views::ScrollBar* scroll_bar, void OnScrollBarUpdated(views::ScrollBar* scroll_bar,
int viewport_size, int viewport_size,
......
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