Commit ed77af3a authored by David Black's avatar David Black Committed by Commit Bot

Implement DialogPlate motion spec.

Known issues
- Settings icon fades in/out. Will address in follow up.
- ActionView is just a wrapper now for a LogoView. Will do a follow up
  CL to further clean this up.

See bug for spec/demo.

Bug: b:111500701
Change-Id: Iee2902f0c34b33cce579a78fb91b4519a2dff8c7
Reviewed-on: https://chromium-review.googlesource.com/1137843
Commit-Queue: David Black <dmblack@google.com>
Reviewed-by: default avatarXiaohui Chen <xiaohuic@chromium.org>
Cr-Commit-Position: refs/heads/master@{#575529}
parent a867c6ff
......@@ -151,6 +151,8 @@ component("ash") {
"assistant/ui/main_stage/suggestion_container_view.h",
"assistant/ui/main_stage/ui_element_container_view.cc",
"assistant/ui/main_stage/ui_element_container_view.h",
"assistant/util/animation_util.cc",
"assistant/util/animation_util.h",
"assistant/util/deep_link_util.cc",
"assistant/util/deep_link_util.h",
"autoclick/autoclick_controller.cc",
......
......@@ -26,10 +26,7 @@ constexpr int kPreferredSizeDip = 26;
ActionView::ActionView(AssistantController* assistant_controller,
ActionViewListener* listener)
: assistant_controller_(assistant_controller),
listener_(listener),
keyboard_action_view_(new views::ImageView()),
voice_action_view_(BaseLogoView::Create()) {
: assistant_controller_(assistant_controller), listener_(listener) {
InitLayout();
UpdateState(/*animate=*/false);
......@@ -49,17 +46,10 @@ gfx::Size ActionView::CalculatePreferredSize() const {
void ActionView::InitLayout() {
SetLayoutManager(std::make_unique<views::FillLayout>());
gfx::Size size = gfx::Size(kPreferredSizeDip, kPreferredSizeDip);
// Keyboard action.
keyboard_action_view_->SetImage(
gfx::CreateVectorIcon(kSendIcon, kPreferredSizeDip, gfx::kGoogleBlue500));
keyboard_action_view_->SetImageSize(size);
keyboard_action_view_->SetPreferredSize(size);
AddChildView(keyboard_action_view_);
// Voice action.
voice_action_view_->SetPreferredSize(size);
voice_action_view_ = BaseLogoView::Create();
voice_action_view_->SetPreferredSize(
gfx::Size(kPreferredSizeDip, kPreferredSizeDip));
AddChildView(voice_action_view_);
}
......@@ -79,10 +69,6 @@ bool ActionView::OnMousePressed(const ui::MouseEvent& event) {
return true;
}
void ActionView::OnInputModalityChanged(InputModality input_modality) {
UpdateState(/*animate=*/false);
}
void ActionView::OnMicStateChanged(MicState mic_state) {
is_user_speaking_ = false;
UpdateState(/*animate=*/true);
......@@ -105,18 +91,6 @@ void ActionView::UpdateState(bool animate) {
const AssistantInteractionModel* interaction_model =
assistant_controller_->interaction_controller()->model();
InputModality input_modality = interaction_model->input_modality();
// We don't need to handle stylus input modality.
if (input_modality == InputModality::kStylus)
return;
if (input_modality == InputModality::kKeyboard) {
voice_action_view_->SetVisible(false);
keyboard_action_view_->SetVisible(true);
return;
}
BaseLogoView::State mic_state;
switch (interaction_model->mic_state()) {
case MicState::kClosed:
......@@ -128,9 +102,6 @@ void ActionView::UpdateState(bool animate) {
break;
}
voice_action_view_->SetState(mic_state, animate);
keyboard_action_view_->SetVisible(false);
voice_action_view_->SetVisible(true);
}
} // namespace ash
......@@ -9,10 +9,6 @@
#include "base/macros.h"
#include "ui/views/view.h"
namespace views {
class ImageView;
} // namespace views
namespace ash {
class ActionView;
......@@ -44,7 +40,6 @@ class ActionView : public views::View,
bool OnMousePressed(const ui::MouseEvent& event) override;
// AssistantInteractionModelObserver:
void OnInputModalityChanged(InputModality input_modality) override;
void OnMicStateChanged(MicState mic_state) override;
void OnSpeechLevelChanged(float speech_level_db) override;
......@@ -58,7 +53,6 @@ class ActionView : public views::View,
AssistantController* const assistant_controller_; // Owned by Shell.
ActionViewListener* listener_;
views::ImageView* keyboard_action_view_; // Owned by view hierarchy.
BaseLogoView* voice_action_view_; // Owned by view hierarchy.
// True when speech level goes above a threshold and sets LogoView in
......
......@@ -10,11 +10,13 @@
#include "ash/assistant/assistant_interaction_controller.h"
#include "ash/assistant/assistant_ui_controller.h"
#include "ash/assistant/ui/assistant_ui_constants.h"
#include "ash/assistant/util/animation_util.h"
#include "ash/public/cpp/vector_icons/vector_icons.h"
#include "ash/resources/vector_icons/vector_icons.h"
#include "ash/strings/grit/ash_strings.h"
#include "base/strings/utf_string_conversions.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/compositor/layer_animator.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/color_palette.h"
#include "ui/gfx/paint_vector_icon.h"
......@@ -33,6 +35,12 @@ namespace {
constexpr int kIconSizeDip = 24;
constexpr int kPreferredHeightDip = 48;
// Animation.
constexpr base::TimeDelta kAnimationFadeInDuration =
base::TimeDelta::FromMilliseconds(100);
constexpr base::TimeDelta kAnimationFadeOutDuration =
base::TimeDelta::FromMilliseconds(83);
// Helpers ---------------------------------------------------------------------
// Creates a settings button. Caller takes ownership.
......@@ -105,6 +113,8 @@ void DialogPlate::InitLayout() {
void DialogPlate::InitKeyboardLayoutContainer() {
keyboard_layout_container_ = new views::View();
keyboard_layout_container_->SetPaintToLayer();
keyboard_layout_container_->layer()->SetFillsBoundsOpaquely(false);
views::BoxLayout* layout_manager =
keyboard_layout_container_->SetLayoutManager(
......@@ -155,6 +165,8 @@ void DialogPlate::InitKeyboardLayoutContainer() {
void DialogPlate::InitVoiceLayoutContainer() {
voice_layout_container_ = new views::View();
voice_layout_container_->SetPaintToLayer();
voice_layout_container_->layer()->SetFillsBoundsOpaquely(false);
views::BoxLayout* layout_manager = voice_layout_container_->SetLayoutManager(
std::make_unique<views::BoxLayout>(
......@@ -215,18 +227,38 @@ void DialogPlate::OnButtonPressed(DialogPlateButtonId id) {
void DialogPlate::OnInputModalityChanged(InputModality input_modality) {
switch (input_modality) {
case InputModality::kKeyboard:
keyboard_layout_container_->SetVisible(true);
voice_layout_container_->SetVisible(false);
// When switching to text input modality we give focus to the textfield.
// Animate voice layout container opacity to 0%.
voice_layout_container_->layer()->GetAnimator()->StartAnimation(
assistant::util::CreateLayerAnimationSequence(
ui::LayerAnimationElement::CreateOpacityElement(
0.f, kAnimationFadeOutDuration)));
// Animate keyboard layout container opacity to 100% with delay.
keyboard_layout_container_->layer()->GetAnimator()->StartAnimation(
assistant::util::CreateLayerAnimationSequenceWithDelay(
ui::LayerAnimationElement::CreateOpacityElement(
1.f, kAnimationFadeInDuration),
/*delay=*/kAnimationFadeOutDuration));
// When switching to keyboard input modality, we focus the textfield.
textfield_->RequestFocus();
break;
case InputModality::kVoice:
keyboard_layout_container_->SetVisible(false);
voice_layout_container_->SetVisible(true);
// Animate keyboard layout container opacity to 0%.
keyboard_layout_container_->layer()->GetAnimator()->StartAnimation(
assistant::util::CreateLayerAnimationSequence(
ui::LayerAnimationElement::CreateOpacityElement(
0.f, kAnimationFadeOutDuration)));
// Animate voice layout container opacity to 100% with delay;
voice_layout_container_->layer()->GetAnimator()->StartAnimation(
assistant::util::CreateLayerAnimationSequenceWithDelay(
ui::LayerAnimationElement::CreateOpacityElement(
1.f, kAnimationFadeInDuration),
/*delay=*/kAnimationFadeOutDuration));
break;
case InputModality::kStylus:
// Not action necessary.
// No action necessary.
break;
}
}
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ash/assistant/util/animation_util.h"
#include "base/time/time.h"
#include "ui/compositor/layer_animation_element.h"
#include "ui/compositor/layer_animation_sequence.h"
namespace ash {
namespace assistant {
namespace util {
ui::LayerAnimationSequence* CreateLayerAnimationSequence(
std::unique_ptr<ui::LayerAnimationElement> layer_animation_element) {
return CreateLayerAnimationSequenceWithDelay(
std::move(layer_animation_element),
/*delay=*/base::TimeDelta());
}
ui::LayerAnimationSequence* CreateLayerAnimationSequenceWithDelay(
std::unique_ptr<ui::LayerAnimationElement> layer_animation_element,
base::TimeDelta delay) {
DCHECK(delay.InMilliseconds() >= 0);
ui::LayerAnimationSequence* layer_animation_sequence =
new ui::LayerAnimationSequence();
if (!delay.is_zero()) {
layer_animation_sequence->AddElement(
ui::LayerAnimationElement::CreatePauseElement(
layer_animation_element->properties(), delay));
}
layer_animation_sequence->AddElement(std::move(layer_animation_element));
return layer_animation_sequence;
}
} // namespace util
} // namespace assistant
} // namespace ash
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ASH_ASSISTANT_UTIL_ANIMATION_UTIL_H_
#define ASH_ASSISTANT_UTIL_ANIMATION_UTIL_H_
#include <memory>
namespace base {
class TimeDelta;
} // namespace base
namespace ui {
class LayerAnimationElement;
class LayerAnimationSequence;
} // namespace ui
namespace ash {
namespace assistant {
namespace util {
// Creates a LayerAnimationSequence containing the specified
// |layer_animation_element|. The method caller assumes ownership of the
// returned pointer.
ui::LayerAnimationSequence* CreateLayerAnimationSequence(
std::unique_ptr<ui::LayerAnimationElement> layer_animation_element);
// Creates a LayerAnimationSequence containing the specified
// |layer_animation_element| to be started after the given |delay|. The method
// caller assumes ownership of the returned pointer.
ui::LayerAnimationSequence* CreateLayerAnimationSequenceWithDelay(
std::unique_ptr<ui::LayerAnimationElement> layer_animation_element,
base::TimeDelta delay);
} // namespace util
} // namespace assistant
} // namespace ash
#endif // ASH_ASSISTANT_UTIL_ANIMATION_UTIL_H_
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