| // Copyright 2019 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/system/accessibility/autoclick_menu_view.h" |
| |
| #include "ash/accessibility/accessibility_controller_impl.h" |
| #include "ash/resources/vector_icons/vector_icons.h" |
| #include "ash/shell.h" |
| #include "ash/strings/grit/ash_strings.h" |
| #include "ash/style/ash_color_provider.h" |
| #include "ash/system/accessibility/floating_menu_button.h" |
| #include "ash/system/tray/tray_constants.h" |
| #include "ash/system/unified/top_shortcut_button.h" |
| #include "base/bind.h" |
| #include "base/metrics/histogram_macros.h" |
| #include "base/metrics/user_metrics.h" |
| #include "ui/base/l10n/l10n_util.h" |
| #include "ui/gfx/canvas.h" |
| #include "ui/gfx/paint_vector_icon.h" |
| #include "ui/gfx/vector_icon_types.h" |
| #include "ui/views/accessibility/view_accessibility.h" |
| #include "ui/views/border.h" |
| #include "ui/views/controls/button/button.h" |
| #include "ui/views/controls/separator.h" |
| #include "ui/views/layout/box_layout.h" |
| #include "ui/views/metadata/metadata_impl_macros.h" |
| |
| namespace ash { |
| |
| namespace { |
| |
| // Constants for panel sizing, positioning and coloring. |
| const int kPanelPositionButtonSize = 36; |
| const int kPanelPositionButtonPadding = 14; |
| const int kSeparatorHeight = 16; |
| |
| } // namespace |
| |
| AutoclickMenuView::AutoclickMenuView(AutoclickEventType type, |
| FloatingMenuPosition position) { |
| int total_height = kUnifiedTopShortcutSpacing * 2 + kTrayItemSize; |
| int separator_spacing = (total_height - kSeparatorHeight) / 2; |
| views::Builder<AutoclickMenuView>(this) |
| .SetCrossAxisAlignment(views::BoxLayout::CrossAxisAlignment::kEnd) |
| .AddChildren( |
| {views::Builder<views::BoxLayoutView>() |
| .SetInsideBorderInsets(kUnifiedMenuItemPadding) |
| .SetBetweenChildSpacing(kUnifiedTopShortcutSpacing) |
| .AddChildren( |
| {views::Builder<FloatingMenuButton>() |
| .CopyAddressTo(&left_click_button_) |
| .SetID(static_cast<int>(ButtonId::kLeftClick)) |
| .SetVectorIcon(kAutoclickLeftClickIcon) |
| .SetTooltipText(l10n_util::GetStringUTF16( |
| IDS_ASH_AUTOCLICK_OPTION_LEFT_CLICK)) |
| .SetCallback(base::BindRepeating( |
| &AutoclickMenuView::OnAutoclickButtonPressed, |
| base::Unretained(this), |
| base::Unretained(left_click_button_))), |
| views::Builder<FloatingMenuButton>() |
| .CopyAddressTo(&right_click_button_) |
| .SetID(static_cast<int>(ButtonId::kRightClick)) |
| .SetVectorIcon(kAutoclickRightClickIcon) |
| .SetTooltipText(l10n_util::GetStringUTF16( |
| IDS_ASH_AUTOCLICK_OPTION_RIGHT_CLICK)) |
| .SetCallback(base::BindRepeating( |
| &AutoclickMenuView::OnAutoclickButtonPressed, |
| base::Unretained(this), |
| base::Unretained(right_click_button_))), |
| views::Builder<FloatingMenuButton>() |
| .CopyAddressTo(&double_click_button_) |
| .SetID(static_cast<int>(ButtonId::kDoubleClick)) |
| .SetVectorIcon(kAutoclickDoubleClickIcon) |
| .SetTooltipText(l10n_util::GetStringUTF16( |
| IDS_ASH_AUTOCLICK_OPTION_DOUBLE_CLICK)) |
| .SetCallback(base::BindRepeating( |
| &AutoclickMenuView::OnAutoclickButtonPressed, |
| base::Unretained(this), |
| base::Unretained(double_click_button_))), |
| views::Builder<FloatingMenuButton>() |
| .CopyAddressTo(&drag_button_) |
| .SetID(static_cast<int>(ButtonId::kDragAndDrop)) |
| .SetVectorIcon(kAutoclickDragIcon) |
| .SetTooltipText(l10n_util::GetStringUTF16( |
| IDS_ASH_AUTOCLICK_OPTION_DRAG_AND_DROP)) |
| .SetCallback(base::BindRepeating( |
| &AutoclickMenuView::OnAutoclickButtonPressed, |
| base::Unretained(this), |
| base::Unretained(drag_button_))), |
| views::Builder<FloatingMenuButton>() |
| .CopyAddressTo(&scroll_button_) |
| .SetID(static_cast<int>(ButtonId::kScroll)) |
| .SetVectorIcon(kAutoclickScrollIcon) |
| .SetTooltipText(l10n_util::GetStringUTF16( |
| IDS_ASH_AUTOCLICK_OPTION_SCROLL)) |
| .SetCallback(base::BindRepeating( |
| &AutoclickMenuView::OnAutoclickButtonPressed, |
| base::Unretained(this), |
| base::Unretained(scroll_button_))), |
| views::Builder<FloatingMenuButton>() |
| .CopyAddressTo(&pause_button_) |
| .SetID(static_cast<int>(ButtonId::kPause)) |
| .SetVectorIcon(kAutoclickPauseIcon) |
| .SetTooltipText(l10n_util::GetStringUTF16( |
| IDS_ASH_AUTOCLICK_OPTION_NO_ACTION)) |
| .SetCallback(base::BindRepeating( |
| &AutoclickMenuView::OnAutoclickButtonPressed, |
| base::Unretained(this), |
| base::Unretained(pause_button_)))}), |
| views::Builder<views::Separator>() |
| .SetColor(AshColorProvider::Get()->GetContentLayerColor( |
| AshColorProvider::ContentLayerType::kSeparatorColor)) |
| .SetPreferredHeight(kSeparatorHeight) |
| .SetBorder(views::CreateEmptyBorder( |
| separator_spacing - kUnifiedTopShortcutSpacing, 0, |
| separator_spacing, 0)), |
| views::Builder<views::BoxLayoutView>() |
| .SetInsideBorderInsets(gfx::Insets( |
| 0, kPanelPositionButtonPadding, kPanelPositionButtonPadding, |
| kPanelPositionButtonPadding)) |
| .SetBetweenChildSpacing(kPanelPositionButtonPadding) |
| .AddChildren( |
| {views::Builder<FloatingMenuButton>() |
| .CopyAddressTo(&position_button_) |
| .SetID(static_cast<int>(ButtonId::kPosition)) |
| .SetVectorIcon(kAutoclickPositionBottomLeftIcon) |
| .SetPreferredSize(gfx::Size(kPanelPositionButtonSize, |
| kPanelPositionButtonSize)) |
| .SetTooltipText(l10n_util::GetStringUTF16( |
| IDS_ASH_AUTOCLICK_OPTION_CHANGE_POSITION)) |
| .SetDrawHighlight(false) |
| .SetA11yTogglable(false) |
| .SetCallback(base::BindRepeating( |
| &AutoclickMenuView::OnPositionButtonPressed, |
| base::Unretained(this)))})}) |
| .BuildChildren(); |
| UpdateEventType(type); |
| UpdatePosition(position); |
| } |
| |
| void AutoclickMenuView::UpdateEventType(AutoclickEventType type) { |
| left_click_button_->SetToggled(type == AutoclickEventType::kLeftClick); |
| right_click_button_->SetToggled(type == AutoclickEventType::kRightClick); |
| double_click_button_->SetToggled(type == AutoclickEventType::kDoubleClick); |
| drag_button_->SetToggled(type == AutoclickEventType::kDragAndDrop); |
| scroll_button_->SetToggled(type == AutoclickEventType::kScroll); |
| pause_button_->SetToggled(type == AutoclickEventType::kNoAction); |
| if (type != AutoclickEventType::kNoAction) |
| event_type_ = type; |
| } |
| |
| void AutoclickMenuView::UpdatePosition(FloatingMenuPosition position) { |
| switch (position) { |
| case FloatingMenuPosition::kBottomRight: |
| position_button_->SetVectorIcon(kAutoclickPositionBottomRightIcon); |
| return; |
| case FloatingMenuPosition::kBottomLeft: |
| position_button_->SetVectorIcon(kAutoclickPositionBottomLeftIcon); |
| return; |
| case FloatingMenuPosition::kTopLeft: |
| position_button_->SetVectorIcon(kAutoclickPositionTopLeftIcon); |
| return; |
| case FloatingMenuPosition::kTopRight: |
| position_button_->SetVectorIcon(kAutoclickPositionTopRightIcon); |
| return; |
| case FloatingMenuPosition::kSystemDefault: |
| position_button_->SetVectorIcon(base::i18n::IsRTL() |
| ? kAutoclickPositionBottomLeftIcon |
| : kAutoclickPositionBottomRightIcon); |
| return; |
| } |
| } |
| |
| void AutoclickMenuView::OnAutoclickButtonPressed(views::Button* sender) { |
| AutoclickEventType type; |
| if (sender == left_click_button_) { |
| type = AutoclickEventType::kLeftClick; |
| } else if (sender == right_click_button_) { |
| type = AutoclickEventType::kRightClick; |
| } else if (sender == double_click_button_) { |
| type = AutoclickEventType::kDoubleClick; |
| } else if (sender == drag_button_) { |
| type = AutoclickEventType::kDragAndDrop; |
| } else if (sender == scroll_button_) { |
| type = AutoclickEventType::kScroll; |
| } else if (sender == pause_button_) { |
| // If the pause button was already selected, tapping it again turns off |
| // pause and returns to the previous type. |
| type = pause_button_->GetToggled() ? event_type_ |
| : AutoclickEventType::kNoAction; |
| } else { |
| return; |
| } |
| |
| Shell::Get()->accessibility_controller()->SetAutoclickEventType(type); |
| UMA_HISTOGRAM_ENUMERATION("Accessibility.CrosAutoclick.TrayMenu.ChangeAction", |
| type); |
| } |
| |
| void AutoclickMenuView::OnPositionButtonPressed() { |
| FloatingMenuPosition new_position; |
| // Rotate clockwise throughout the screen positions. |
| switch ( |
| Shell::Get()->accessibility_controller()->GetAutoclickMenuPosition()) { |
| case FloatingMenuPosition::kBottomRight: |
| new_position = FloatingMenuPosition::kBottomLeft; |
| break; |
| case FloatingMenuPosition::kBottomLeft: |
| new_position = FloatingMenuPosition::kTopLeft; |
| break; |
| case FloatingMenuPosition::kTopLeft: |
| new_position = FloatingMenuPosition::kTopRight; |
| break; |
| case FloatingMenuPosition::kTopRight: |
| new_position = FloatingMenuPosition::kBottomRight; |
| break; |
| case FloatingMenuPosition::kSystemDefault: |
| new_position = base::i18n::IsRTL() ? FloatingMenuPosition::kTopLeft |
| : FloatingMenuPosition::kBottomLeft; |
| break; |
| } |
| Shell::Get()->accessibility_controller()->SetAutoclickMenuPosition( |
| new_position); |
| base::RecordAction(base::UserMetricsAction( |
| "Accessibility.CrosAutoclick.TrayMenu.ChangePosition")); |
| } |
| |
| BEGIN_METADATA(AutoclickMenuView, views::BoxLayoutView) |
| END_METADATA |
| |
| } // namespace ash |