Commit adf1a9f6 authored by My Nguyen's avatar My Nguyen Committed by Commit Bot

Add ability to tap/click to accept suggestion

This is described in http://go/e14s-emoji-addition-mock for emoji and
http://go/personal-info-suggestion-mock for personal info suggestion.

Bug: 1098057
Change-Id: Idb66d47db2f60c9da7344fffc68ab771c981a80e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2257659Reviewed-by: default avatarKeith Lee <keithlee@chromium.org>
Reviewed-by: default avatarDarren Shen <shend@chromium.org>
Commit-Queue: My Nguyen <myy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#782852}
parent b2da7772
......@@ -267,6 +267,13 @@ bool AssistiveSuggester::Suggest(const base::string16& text,
return false;
}
void AssistiveSuggester::AcceptSuggestion(size_t index) {
if (current_suggester_ && current_suggester_->AcceptSuggestion(index)) {
RecordAssistiveSuccess(current_suggester_->GetProposeActionType());
current_suggester_ = nullptr;
}
}
void AssistiveSuggester::DismissSuggestion() {
if (current_suggester_)
current_suggester_->DismissSuggestion();
......
......@@ -47,6 +47,9 @@ class AssistiveSuggester {
// Returns true if suggester handles the event and it should stop propagate.
bool OnKeyEvent(const InputMethodEngineBase::KeyboardEvent& event);
// Accepts the suggestion at a given index if a suggester is currently active.
void AcceptSuggestion(size_t index);
private:
// Returns if any suggestion text should be displayed according to the
// surrounding text information.
......
......@@ -124,12 +124,9 @@ SuggestionStatus EmojiSuggester::HandleKeyEvent(
return SuggestionStatus::kNotHandled;
SuggestionStatus status = SuggestionStatus::kNotHandled;
std::string error;
if (event.key == "Enter" && candidate_id_ != -1) {
suggestion_shown_ = false;
engine_->AcceptSuggestionCandidate(context_id_, candidates_[candidate_id_],
&error);
RecordAcceptanceIndex(candidate_id_);
status = SuggestionStatus::kAccept;
if (event.key == "Enter") {
if (AcceptSuggestion(candidate_id_))
status = SuggestionStatus::kAccept;
} else if (event.key == "Down") {
candidate_id_ < static_cast<int>(candidates_.size()) - 1
? candidate_id_++
......@@ -182,6 +179,22 @@ void EmojiSuggester::ShowSuggestion(const std::string& text) {
}
}
bool EmojiSuggester::AcceptSuggestion(size_t index) {
if (index < 0 || index >= candidates_.size())
return false;
std::string error;
engine_->AcceptSuggestionCandidate(context_id_, candidates_[index], &error);
if (!error.empty()) {
LOG(ERROR) << "Failed to accept suggestion. " << error;
}
suggestion_shown_ = false;
RecordAcceptanceIndex(index);
return true;
}
void EmojiSuggester::DismissSuggestion() {
std::string error;
suggestion_shown_ = false;
......
......@@ -27,6 +27,7 @@ class EmojiSuggester : public Suggester {
SuggestionStatus HandleKeyEvent(
const InputMethodEngineBase::KeyboardEvent& event) override;
bool Suggest(const base::string16& text) override;
bool AcceptSuggestion(size_t index) override;
void DismissSuggestion() override;
AssistiveType GetProposeActionType() override;
......
......@@ -227,7 +227,13 @@ void NativeInputMethodEngine::ImeObserver::OnCandidateClicked(
void NativeInputMethodEngine::ImeObserver::OnAssistiveWindowButtonClicked(
const ui::ime::AssistiveWindowButton& button) {
base_observer_->OnAssistiveWindowButtonClicked(button);
if (button.id == ui::ime::ButtonId::kSuggestion) {
if (assistive_suggester_->IsAssistiveFeatureEnabled()) {
assistive_suggester_->AcceptSuggestion(button.index);
}
} else {
base_observer_->OnAssistiveWindowButtonClicked(button);
}
}
void NativeInputMethodEngine::ImeObserver::OnMenuItemActivated(
......
......@@ -133,10 +133,11 @@ SuggestionStatus PersonalInfoSuggester::HandleKeyEvent(
const InputMethodEngineBase::KeyboardEvent& event) {
if (suggestion_shown_) {
if (event.key == "Tab" || event.key == "Right") {
AcceptSuggestion();
IncrementPrefValueTilCapped(kPersonalInfoSuggesterTabAcceptanceCount,
kMaxTabAcceptanceCount);
return SuggestionStatus::kAccept;
if (AcceptSuggestion()) {
IncrementPrefValueTilCapped(kPersonalInfoSuggesterTabAcceptanceCount,
kMaxTabAcceptanceCount);
return SuggestionStatus::kAccept;
}
} else if (event.key == "Esc") {
DismissSuggestion();
return SuggestionStatus::kDismiss;
......@@ -290,15 +291,20 @@ AssistiveType PersonalInfoSuggester::GetProposeActionType() {
return proposed_action_type_;
}
void PersonalInfoSuggester::AcceptSuggestion() {
bool PersonalInfoSuggester::AcceptSuggestion(size_t index) {
std::string error;
suggestion_shown_ = false;
suggestion_handler_->AcceptSuggestion(context_id_, &error);
if (!error.empty()) {
LOG(ERROR) << "Failed to accept suggestion. " << error;
return false;
}
suggestion_shown_ = false;
tts_handler_->Announce(base::StringPrintf(
"Inserted suggestion %s.", base::UTF16ToUTF8(suggestion_).c_str()));
return true;
}
void PersonalInfoSuggester::DismissSuggestion() {
......
......@@ -77,6 +77,8 @@ class PersonalInfoSuggester : public Suggester {
SuggestionStatus HandleKeyEvent(
const InputMethodEngineBase::KeyboardEvent& event) override;
bool Suggest(const base::string16& text) override;
// index defaults to 0 as not required for this suggester.
bool AcceptSuggestion(size_t index = 0) override;
void DismissSuggestion() override;
AssistiveType GetProposeActionType() override;
......@@ -87,8 +89,6 @@ class PersonalInfoSuggester : public Suggester {
void ShowSuggestion(const base::string16& text,
const size_t confirmed_length);
void AcceptSuggestion();
int GetPrefValue(const std::string& pref_name);
// Increment int value for the given pref_name by 1 every time the function is
......
......@@ -34,6 +34,10 @@ class Suggester {
// information.
virtual bool Suggest(const base::string16& text) = 0;
// Accepts the suggestion at a given index, index can be made default if
// unnecessary. Returns true if suggestion is accepted successfully.
virtual bool AcceptSuggestion(size_t index) = 0;
virtual void DismissSuggestion() = 0;
// Return the propose assistive action type.
......
......@@ -5,6 +5,7 @@
#ifndef CHROME_BROWSER_CHROMEOS_INPUT_METHOD_UI_ASSISTIVE_DELEGATE_H_
#define CHROME_BROWSER_CHROMEOS_INPUT_METHOD_UI_ASSISTIVE_DELEGATE_H_
#include "base/strings/string16.h"
#include "ui/chromeos/ui_chromeos_export.h"
namespace ui {
......@@ -15,6 +16,7 @@ enum class ButtonId {
kUndo,
kAddToDictionary,
kSmartInputsSettingLink,
kSuggestion,
};
enum class AssistiveWindowType {
......@@ -26,6 +28,7 @@ enum class AssistiveWindowType {
struct AssistiveWindowButton {
ButtonId id = ButtonId::kNone;
AssistiveWindowType window_type = AssistiveWindowType::kNone;
size_t index = -1;
};
class UI_CHROMEOS_EXPORT AssistiveDelegate {
......
......@@ -66,7 +66,8 @@ std::unique_ptr<views::Label> CreateAnnotationLabel() {
} // namespace
SuggestionView::SuggestionView() {
SuggestionView::SuggestionView(views::ButtonListener* listener)
: views::Button(listener) {
index_label_ = AddChildView(CreateIndexLabel());
index_label_->SetVisible(false);
suggestion_label_ = AddChildView(CreateSuggestionLabel());
......
......@@ -8,6 +8,7 @@
#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "ui/chromeos/ui_chromeos_export.h"
#include "ui/views/controls/button/button.h"
#include "ui/views/controls/label.h"
#include "ui/views/controls/styled_label.h"
#include "ui/views/view.h"
......@@ -34,9 +35,9 @@ constexpr SkColor kButtonHighlightColor =
SkColorSetA(SK_ColorBLACK, 0x0F); // 6% Black.
// SuggestionView renders a suggestion.
class UI_CHROMEOS_EXPORT SuggestionView : public views::View {
class UI_CHROMEOS_EXPORT SuggestionView : public views::Button {
public:
SuggestionView();
explicit SuggestionView(views::ButtonListener* listener);
~SuggestionView() override;
void SetView(const SuggestionDetails& details);
......
......@@ -77,7 +77,8 @@ class SettingLinkView : public views::View {
};
SuggestionWindowView::SuggestionWindowView(gfx::NativeView parent,
AssistiveDelegate* delegate) {
AssistiveDelegate* delegate)
: delegate_(delegate) {
DialogDelegate::SetButtons(ui::DIALOG_BUTTON_NONE);
SetCanActivate(false);
DCHECK(parent);
......@@ -146,7 +147,7 @@ void SuggestionWindowView::MaybeInitializeSuggestionViews(
candidate_views_.resize(candidates_size);
while (candidate_views_.size() < candidates_size) {
auto new_candidate = std::make_unique<SuggestionView>();
auto new_candidate = std::make_unique<SuggestionView>(this);
candidate_area_->AddChildView(new_candidate.get());
candidate_views_.push_back(std::move(new_candidate));
}
......@@ -165,6 +166,20 @@ void SuggestionWindowView::SetBounds(const gfx::Rect& cursor_bounds) {
SetAnchorRect(cursor_bounds);
}
// TODO(crbug/1099116): Add test for ButtonPressed.
void SuggestionWindowView::ButtonPressed(views::Button* sender,
const ui::Event& event) {
for (size_t i = 0; i < candidate_views_.size(); i++) {
if (sender == candidate_views_[i].get()) {
AssistiveWindowButton button;
button.id = ui::ime::ButtonId::kSuggestion;
button.index = i;
delegate_->AssistiveWindowButtonClicked(button);
return;
}
}
}
const char* SuggestionWindowView::GetClassName() const {
return "SuggestionWindowView";
}
......
......@@ -10,6 +10,7 @@
#include "base/macros.h"
#include "ui/chromeos/ui_chromeos_export.h"
#include "ui/views/bubble/bubble_dialog_delegate_view.h"
#include "ui/views/controls/button/button.h"
namespace ui {
namespace ime {
......@@ -22,7 +23,8 @@ struct SuggestionDetails;
// SuggestionWindowView is the main container of the suggestion window UI.
class UI_CHROMEOS_EXPORT SuggestionWindowView
: public views::BubbleDialogDelegateView {
: public views::BubbleDialogDelegateView,
public views::ButtonListener {
public:
SuggestionWindowView(gfx::NativeView parent, AssistiveDelegate* delegate);
~SuggestionWindowView() override;
......@@ -43,6 +45,9 @@ class UI_CHROMEOS_EXPORT SuggestionWindowView
private:
friend class SuggestionWindowViewTest;
// Overridden from views::ButtonListener:
void ButtonPressed(views::Button* sender, const ui::Event& event) override;
void MaybeInitializeSuggestionViews(size_t candidates_size);
void MakeVisible();
......
......@@ -117,6 +117,7 @@ input_ime::AssistiveWindowButton ConvertAssistiveWindowButton(
switch (id) {
case ui::ime::ButtonId::kNone:
case ui::ime::ButtonId::kSmartInputsSettingLink:
case ui::ime::ButtonId::kSuggestion:
return input_ime::ASSISTIVE_WINDOW_BUTTON_NONE;
case ui::ime::ButtonId::kUndo:
return input_ime::ASSISTIVE_WINDOW_BUTTON_UNDO;
......
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