Skip to content

Commit

Permalink
arc/gio: Changing binding between key and mouse for ActionTap
Browse files Browse the repository at this point in the history
Implement the action edit menu (3dot menu) for changing the binding
between mouse and keyboard for ActionTap.

Pending on adding UI to notify users the key for lock/unlock the mouse.

Bug: b:188452744
Test: mannual test and unittest
Change-Id: I81f937bf25c45dc24a808d89bef1c33e8a4e2d77
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3561013
Reviewed-by: David Jacobo <djacobo@chromium.org>
Commit-Queue: Cici Ruan <cuicuiruan@google.com>
Auto-Submit: Cici Ruan <cuicuiruan@google.com>
Cr-Commit-Position: refs/heads/main@{#988690}
  • Loading branch information
Cici Ruan authored and Chromium LUCI CQ committed Apr 4, 2022
1 parent d9f0394 commit e78c7a0
Show file tree
Hide file tree
Showing 12 changed files with 108 additions and 26 deletions.
3 changes: 2 additions & 1 deletion chrome/browser/ash/arc/input_overlay/actions/action.cc
Original file line number Diff line number Diff line change
Expand Up @@ -235,11 +235,12 @@ void Action::CancelPendingBind(const gfx::RectF& content_bounds) {

void Action::RestoreToDefault(const gfx::RectF& content_bounds) {
DCHECK(action_view_);
if (!action_view_)
if (!action_view_ || GetCurrentDisplayedBinding() == *original_binding_)
return;
pending_binding_.reset();
pending_binding_ = std::make_unique<InputElement>(*original_binding_);
action_view_->SetViewContent(BindingOption::kPending, content_bounds);
action_view_->SetDisplayMode(DisplayMode::kEdited);
}

const InputElement& Action::GetCurrentDisplayedBinding() {
Expand Down
7 changes: 6 additions & 1 deletion chrome/browser/ash/arc/input_overlay/actions/action.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,12 +103,17 @@ class Action {
InputElement* current_binding() const { return current_binding_.get(); }
InputElement* original_binding() const { return original_binding_.get(); }
InputElement* pending_binding() const { return pending_binding_.get(); }
void set_pending_binding(std::unique_ptr<InputElement> binding) {
if (pending_binding_)
pending_binding_.reset();
pending_binding_ = std::move(binding);
}
const std::string& name() { return name_; }
const std::vector<std::unique_ptr<Position>>& locations() const {
return locations_;
}
bool require_mouse_locked() const { return require_mouse_locked_; }
const aura::Window* target_window() const { return target_window_; }
aura::Window* target_window() const { return target_window_; }
int current_position_index() const { return current_position_index_; }
const absl::optional<int> touch_id() const { return touch_id_; }
bool on_left_or_middle_side() const { return on_left_or_middle_side_; }
Expand Down
10 changes: 9 additions & 1 deletion chrome/browser/ash/arc/input_overlay/actions/action_move.cc
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,11 @@ class ActionMove::ActionMoveMouseView : public ActionView {
}

// TODO(cuicuiruan): rewrite for post MVP once design is ready.
void OnKeyBindingChange(ActionTag* action_tag, ui::DomCode code) override {}
void OnKeyBindingChange(ActionTag* action_tag, ui::DomCode code) override {
NOTIMPLEMENTED();
}
void OnBindingToKeyboard() override { NOTIMPLEMENTED(); }
void OnBindingToMouse(std::string mouse_action) override { NOTIMPLEMENTED(); }
};

class ActionMove::ActionMoveKeyView : public ActionView {
Expand Down Expand Up @@ -144,6 +148,10 @@ class ActionMove::ActionMoveKeyView : public ActionView {
// TODO(cuicuiruan): Implement the key binding change for key-bound
// |ActionMove|.
}

// TODO(cuicuiruan): implement for post MVP once the design is ready.
void OnBindingToKeyboard() override { NOTIMPLEMENTED(); }
void OnBindingToMouse(std::string mouse_action) override { NOTIMPLEMENTED(); }
};

ActionMove::ActionMove(aura::Window* window) : Action(window) {}
Expand Down
30 changes: 28 additions & 2 deletions chrome/browser/ash/arc/input_overlay/actions/action_tap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,34 @@ class ActionTap::ActionTapView : public ActionView {
return;

auto input_element = InputElement::CreateActionTapKeyElement(code);
display_overlay_controller_->OnKeyBindingChange(action_,
std::move(input_element));
display_overlay_controller_->OnBindingChange(action_,
std::move(input_element));
}

void OnBindingToKeyboard() override {
const auto& binding = action_->GetCurrentDisplayedBinding();
if (!IsMouseBound(binding))
return;

auto input_element = std::make_unique<InputElement>();
action_->set_pending_binding(std::move(input_element));
auto bounds = CalculateWindowContentBounds(action_->target_window());
SetViewContent(BindingOption::kPending, bounds);
SetDisplayMode(DisplayMode::kEdited);
}

void OnBindingToMouse(std::string mouse_action) override {
DCHECK(mouse_action == kPrimaryClick || mouse_action == kSecondaryClick);
if (mouse_action != kPrimaryClick && mouse_action != kSecondaryClick)
return;
const auto& binding = action_->GetCurrentDisplayedBinding();
if (IsMouseBound(binding) && binding.mouse_action() == mouse_action)
return;

auto input_element =
InputElement::CreateActionTapMouseElement(mouse_action);
display_overlay_controller_->OnBindingChange(action_,
std::move(input_element));
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ void DisplayOverlayController::RemoveEditErrorMsg() {
error_ = nullptr;
}

void DisplayOverlayController::OnKeyBindingChange(
void DisplayOverlayController::OnBindingChange(
Action* action,
std::unique_ptr<InputElement> input_element) {
touch_injector_->OnBindingChange(action, std::move(input_element));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ class DisplayOverlayController : public ui::EventHandler {
void AddEditErrorMsg(ActionView* action_view, base::StringPiece error_msg);
void RemoveEditErrorMsg();

void OnKeyBindingChange(Action* action,
std::unique_ptr<InputElement> input_element);
void OnBindingChange(Action* action,
std::unique_ptr<InputElement> input_element);

// Save the changes when users press the save button after editing.
void OnCustomizeSave();
Expand Down
12 changes: 10 additions & 2 deletions chrome/browser/ash/arc/input_overlay/touch_injector.cc
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,10 @@ constexpr char kTapAction[] = "tap";
constexpr char kMoveAction[] = "move";
constexpr char kMouseLock[] = "mouse_lock";
// Mask for interesting modifiers.
const int kInterestingFlagsMask =
constexpr int kInterestingFlagsMask =
ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN;
// Default mouse lock key.
constexpr ui::DomCode kDefaultMouseLockCode = ui::DomCode::ESCAPE;

// UI strings.
// TODO(cuicuiruan): move the strings to chrome/app/generated_resources.grd
Expand Down Expand Up @@ -275,11 +277,17 @@ void TouchInjector::SendExtraEvent(

void TouchInjector::ParseMouseLock(const base::Value& value) {
auto* mouse_lock = value.FindKey(kMouseLock);
if (!mouse_lock)
if (!mouse_lock) {
mouse_lock_ = std::make_unique<KeyCommand>(
kDefaultMouseLockCode, /*modifier=*/0,
base::BindRepeating(&TouchInjector::FlipMouseLockFlag,
weak_ptr_factory_.GetWeakPtr()));
return;
}
auto key = ParseKeyboardKey(*mouse_lock, kMouseLock);
if (!key)
return;
// Customized mouse lock overrides the default mouse lock.
mouse_lock_ = std::make_unique<KeyCommand>(
key->first, key->second,
base::BindRepeating(&TouchInjector::FlipMouseLockFlag,
Expand Down
41 changes: 29 additions & 12 deletions chrome/browser/ash/arc/input_overlay/ui/action_edit_menu.cc
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ ActionEditMenu::ActionEditMenu(
DisplayOverlayController* display_overlay_controller,
ActionView* anchor)
: display_overlay_controller_(display_overlay_controller),
anchor_(anchor) {}
anchor_view_(anchor) {}

ActionEditMenu::~ActionEditMenu() = default;

Expand Down Expand Up @@ -118,12 +118,13 @@ void ActionEditMenu::InitActionTapEditMenu() {
base::Unretained(this)),
IDS_INPUT_OVERLAY_EDIT_MENU_KEYBOARD_KEY));
mouse_left_ = AddChildView(std::make_unique<BindingButton>(
base::BindRepeating(&ActionEditMenu::OnMouseLeftBindingButtonPressed,
base::BindRepeating(&ActionEditMenu::OnMouseLeftClickBindingButtonPressed,
base::Unretained(this)),
IDS_INPUT_OVERLAY_EDIT_MENU_LEFT_MOUSE_CLICK));
mouse_right_ = AddChildView(std::make_unique<BindingButton>(
base::BindRepeating(&ActionEditMenu::OnMouseRightBindingButtonPressed,
base::Unretained(this)),
base::BindRepeating(
&ActionEditMenu::OnMouseRightClickBindingButtonPressed,
base::Unretained(this)),
IDS_INPUT_OVERLAY_EDIT_MENU_RIGHT_MOUSE_CLICK));
reset_ = AddChildView(std::make_unique<BindingButton>(
base::BindRepeating(&ActionEditMenu::OnResetButtonPressed,
Expand All @@ -135,8 +136,8 @@ void ActionEditMenu::InitActionTapEditMenu() {
mouse_right_->GetMinSize().width()});
SetBorder(views::CreateEmptyBorder(gfx::Insets::TLBR(8, 0, 8, 0)));
SetSize(gfx::Size(kMenuWidth + additional_width, kMenuHeight));
SetPosition(anchor_->GetEditMenuPosition(size()));
auto* action = anchor_->action();
SetPosition(anchor_view_->GetEditMenuPosition(size()));
auto* action = anchor_view_->action();
// It is possible that the action has no binding after customizing, such as
// users bind the key to another action.
auto& binding = action->GetCurrentDisplayedBinding();
Expand All @@ -154,22 +155,38 @@ void ActionEditMenu::InitActionTapEditMenu() {
}

void ActionEditMenu::OnKeyBoardKeyBindingButtonPressed() {
// TODO(cuicuiruan): Implement feature here.
DCHECK(anchor_view_);
if (!anchor_view_)
return;

anchor_view_->OnBindingToKeyboard();
display_overlay_controller_->RemoveActionEditMenu();
}

void ActionEditMenu::OnMouseLeftBindingButtonPressed() {
// TODO(cuicuiruan): Implement feature here.
void ActionEditMenu::OnMouseLeftClickBindingButtonPressed() {
DCHECK(anchor_view_);
if (!anchor_view_)
return;

anchor_view_->OnBindingToMouse(kPrimaryClick);
display_overlay_controller_->RemoveActionEditMenu();
}

void ActionEditMenu::OnMouseRightBindingButtonPressed() {
// TODO(cuicuiruan): Implement feature here.
void ActionEditMenu::OnMouseRightClickBindingButtonPressed() {
DCHECK(anchor_view_);
if (!anchor_view_)
return;

anchor_view_->OnBindingToMouse(kSecondaryClick);
display_overlay_controller_->RemoveActionEditMenu();
}

void ActionEditMenu::OnResetButtonPressed() {
// TODO(cuicuiruan): Implement feature here.
DCHECK(anchor_view_);
if (!anchor_view_)
return;

anchor_view_->OnResetBinding();
display_overlay_controller_->RemoveActionEditMenu();
}

Expand Down
6 changes: 3 additions & 3 deletions chrome/browser/ash/arc/input_overlay/ui/action_edit_menu.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,14 @@ class ActionEditMenu : public views::View {

void InitActionTapEditMenu();
void OnKeyBoardKeyBindingButtonPressed();
void OnMouseLeftBindingButtonPressed();
void OnMouseRightBindingButtonPressed();
void OnMouseLeftClickBindingButtonPressed();
void OnMouseRightClickBindingButtonPressed();
void OnResetButtonPressed();

// Reference to owner class.
const raw_ptr<DisplayOverlayController> display_overlay_controller_ = nullptr;
// Reference to position.
raw_ptr<ActionView> anchor_ = nullptr;
raw_ptr<ActionView> anchor_view_ = nullptr;
// Reference to the menu items.
raw_ptr<BindingButton> keyboard_key_ = nullptr;
raw_ptr<BindingButton> mouse_left_ = nullptr;
Expand Down
2 changes: 2 additions & 0 deletions chrome/browser/ash/arc/input_overlay/ui/action_label.cc
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,8 @@ void ActionLabel::SetToEditedUnBind() {
SetBackground(views::CreateRoundedRectBackground(kEditedUnboundBgColor,
kCornerRadiusView));
SetSize(GetPreferredSize());
SetSelectable(true);
SetEnabled(true);
}

void ActionLabel::SetToEditFocus() {
Expand Down
11 changes: 11 additions & 0 deletions chrome/browser/ash/arc/input_overlay/ui/action_view.cc
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,17 @@ void ActionView::ShowErrorMsg(base::StringPiece error_msg) {
SetDisplayMode(DisplayMode::kEdited);
}

void ActionView::OnResetBinding() {
const auto& binding = action_->GetCurrentDisplayedBinding();
if (!IsBound(binding) || binding == *action_->current_binding())
return;

auto input_element =
std::make_unique<InputElement>(*(action_->current_binding()));
display_overlay_controller_->OnBindingChange(action_,
std::move(input_element));
}

void ActionView::AddEditButton() {
if (!editable_ || menu_entry_)
return;
Expand Down
6 changes: 5 additions & 1 deletion chrome/browser/ash/arc/input_overlay/ui/action_view.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ class ActionView : public views::View {
const gfx::RectF& content_bounds) = 0;
// Each type of the actions acts differently on key binding change.
virtual void OnKeyBindingChange(ActionTag* action_tag, ui::DomCode code) = 0;
virtual void OnBindingToKeyboard() = 0;
virtual void OnBindingToMouse(std::string mouse_action) = 0;

// Set position from its center position.
void SetPositionFromCenterPosition(gfx::PointF& center_position);
Expand All @@ -46,8 +48,10 @@ class ActionView : public views::View {
// Get edit menu position in parent's bounds.
gfx::Point GetEditMenuPosition(gfx::Size menu_size);
void RemoveEditMenu();

// Show error message for action.
void ShowErrorMsg(base::StringPiece error_msg);
// Reset binding to its previous binding before entering to the edit mode.
void OnResetBinding();

Action* action() { return action_; }
void set_editable(bool editable) { editable_ = editable; }
Expand Down

0 comments on commit e78c7a0

Please sign in to comment.