Commit 319669d4 authored by Andrew Xu's avatar Andrew Xu Committed by Chromium LUCI CQ

[Multipaste] Refactor: Move buttons to independent files

In this CL, the code of MainButton and DeleteButton is moved to
independent files instead of living in clipboard_history_item_view.cc.
It improves the code readability.

This CL should not introduce any visual differences.

Bug: 1151493, 1152815
Change-Id: I16200f26ca1d5321a1407b6703e297f0b7d7fe89
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2556898Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Reviewed-by: default avatarDavid Black <dmblack@google.com>
Commit-Queue: Andrew Xu <andrewxu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#832022}
parent 16df2042
...@@ -323,12 +323,16 @@ component("ash") { ...@@ -323,12 +323,16 @@ component("ash") {
"clipboard/scoped_clipboard_history_pause_impl.h", "clipboard/scoped_clipboard_history_pause_impl.h",
"clipboard/views/clipboard_history_bitmap_item_view.cc", "clipboard/views/clipboard_history_bitmap_item_view.cc",
"clipboard/views/clipboard_history_bitmap_item_view.h", "clipboard/views/clipboard_history_bitmap_item_view.h",
"clipboard/views/clipboard_history_delete_button.cc",
"clipboard/views/clipboard_history_delete_button.h",
"clipboard/views/clipboard_history_file_item_view.cc", "clipboard/views/clipboard_history_file_item_view.cc",
"clipboard/views/clipboard_history_file_item_view.h", "clipboard/views/clipboard_history_file_item_view.h",
"clipboard/views/clipboard_history_item_view.cc", "clipboard/views/clipboard_history_item_view.cc",
"clipboard/views/clipboard_history_item_view.h", "clipboard/views/clipboard_history_item_view.h",
"clipboard/views/clipboard_history_label.cc", "clipboard/views/clipboard_history_label.cc",
"clipboard/views/clipboard_history_label.h", "clipboard/views/clipboard_history_label.h",
"clipboard/views/clipboard_history_main_button.cc",
"clipboard/views/clipboard_history_main_button.h",
"clipboard/views/clipboard_history_text_item_view.cc", "clipboard/views/clipboard_history_text_item_view.cc",
"clipboard/views/clipboard_history_text_item_view.h", "clipboard/views/clipboard_history_text_item_view.h",
"dbus/ash_dbus_services.cc", "dbus/ash_dbus_services.cc",
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "ash/clipboard/clipboard_history_item.h" #include "ash/clipboard/clipboard_history_item.h"
#include "ash/clipboard/clipboard_history_resource_manager.h" #include "ash/clipboard/clipboard_history_resource_manager.h"
#include "ash/clipboard/clipboard_history_util.h" #include "ash/clipboard/clipboard_history_util.h"
#include "ash/clipboard/views/clipboard_history_delete_button.h"
#include "ash/public/cpp/rounded_image_view.h" #include "ash/public/cpp/rounded_image_view.h"
#include "ash/style/ash_color_provider.h" #include "ash/style/ash_color_provider.h"
#include "ash/style/scoped_light_mode_as_default.h" #include "ash/style/scoped_light_mode_as_default.h"
...@@ -196,7 +197,7 @@ class ClipboardHistoryBitmapItemView::BitmapContentsView ...@@ -196,7 +197,7 @@ class ClipboardHistoryBitmapItemView::BitmapContentsView
private: private:
// ContentsView: // ContentsView:
DeleteButton* CreateDeleteButton() override { ClipboardHistoryDeleteButton* CreateDeleteButton() override {
auto delete_button_container = std::make_unique<views::View>(); auto delete_button_container = std::make_unique<views::View>();
auto* layout_manager = delete_button_container->SetLayoutManager( auto* layout_manager = delete_button_container->SetLayoutManager(
std::make_unique<views::BoxLayout>( std::make_unique<views::BoxLayout>(
...@@ -206,10 +207,11 @@ class ClipboardHistoryBitmapItemView::BitmapContentsView ...@@ -206,10 +207,11 @@ class ClipboardHistoryBitmapItemView::BitmapContentsView
layout_manager->set_cross_axis_alignment( layout_manager->set_cross_axis_alignment(
views::BoxLayout::CrossAxisAlignment::kStart); views::BoxLayout::CrossAxisAlignment::kStart);
auto delete_button = std::make_unique<DeleteButton>(container_); auto delete_button =
std::make_unique<ClipboardHistoryDeleteButton>(container_);
delete_button->SetVisible(false); delete_button->SetVisible(false);
delete_button->SetProperty(views::kMarginsKey, kDeleteButtonMargins); delete_button->SetProperty(views::kMarginsKey, kDeleteButtonMargins);
DeleteButton* delete_button_ptr = ClipboardHistoryDeleteButton* delete_button_ptr =
delete_button_container->AddChildView(std::move(delete_button)); delete_button_container->AddChildView(std::move(delete_button));
AddChildView(std::move(delete_button_container)); AddChildView(std::move(delete_button_container));
......
// Copyright 2020 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/clipboard/views/clipboard_history_delete_button.h"
#include "ash/clipboard/views/clipboard_history_item_view.h"
#include "ash/resources/vector_icons/vector_icons.h"
#include "ash/style/ash_color_provider.h"
#include "ash/style/scoped_light_mode_as_default.h"
namespace ash {
namespace {
// The size of the `DeleteButton`.
constexpr int kDeleteButtonSizeDip = 16;
} // namespace
ClipboardHistoryDeleteButton::ClipboardHistoryDeleteButton(
ClipboardHistoryItemView* listener)
: views::ImageButton(base::BindRepeating(
[](ClipboardHistoryItemView* item_view, const ui::Event& event) {
item_view->HandleDeleteButtonPressEvent(event);
},
base::Unretained(listener))) {
SetFocusBehavior(FocusBehavior::ACCESSIBLE_ONLY);
SetAccessibleName(base::ASCIIToUTF16(std::string(GetClassName())));
SetImageHorizontalAlignment(views::ImageButton::ALIGN_CENTER);
SetImageVerticalAlignment(views::ImageButton::ALIGN_MIDDLE);
SetPreferredSize(gfx::Size(kDeleteButtonSizeDip, kDeleteButtonSizeDip));
}
ClipboardHistoryDeleteButton::~ClipboardHistoryDeleteButton() = default;
const char* ClipboardHistoryDeleteButton::GetClassName() const {
return "DeleteButton";
}
void ClipboardHistoryDeleteButton::OnThemeChanged() {
// Use the light mode as default because the light mode is the default mode of
// the native theme which decides the context menu's background color.
// TODO(andrewxu): remove this line after https://crbug.com/1143009 is fixed.
ScopedLightModeAsDefault scoped_light_mode_as_default;
views::ImageButton::OnThemeChanged();
AshColorProvider::Get()->DecorateCloseButton(this, kDeleteButtonSizeDip,
kCloseButtonIcon);
}
} // namespace ash
// Copyright 2020 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_CLIPBOARD_VIEWS_CLIPBOARD_HISTORY_DELETE_BUTTON_H_
#define ASH_CLIPBOARD_VIEWS_CLIPBOARD_HISTORY_DELETE_BUTTON_H_
#include "ui/views/controls/button/image_button.h"
namespace ash {
class ClipboardHistoryItemView;
// The button to delete the menu item and its corresponding clipboard data.
class ClipboardHistoryDeleteButton : public views::ImageButton {
public:
explicit ClipboardHistoryDeleteButton(ClipboardHistoryItemView* listener);
ClipboardHistoryDeleteButton(const ClipboardHistoryDeleteButton& rhs) =
delete;
ClipboardHistoryDeleteButton& operator=(
const ClipboardHistoryDeleteButton& rhs) = delete;
~ClipboardHistoryDeleteButton() override;
private:
// views::ImageButton:
const char* GetClassName() const override;
void OnThemeChanged() override;
};
} // namespace ash
#endif // ASH_CLIPBOARD_VIEWS_CLIPBOARD_HISTORY_DELETE_BUTTON_H_
...@@ -5,26 +5,16 @@ ...@@ -5,26 +5,16 @@
#include "ash/clipboard/views/clipboard_history_item_view.h" #include "ash/clipboard/views/clipboard_history_item_view.h"
#include "ash/clipboard/clipboard_history_item.h" #include "ash/clipboard/clipboard_history_item.h"
#include "ash/clipboard/clipboard_history_resource_manager.h"
#include "ash/clipboard/clipboard_history_util.h"
#include "ash/clipboard/views/clipboard_history_bitmap_item_view.h" #include "ash/clipboard/views/clipboard_history_bitmap_item_view.h"
#include "ash/clipboard/views/clipboard_history_delete_button.h"
#include "ash/clipboard/views/clipboard_history_file_item_view.h" #include "ash/clipboard/views/clipboard_history_file_item_view.h"
#include "ash/clipboard/views/clipboard_history_main_button.h"
#include "ash/clipboard/views/clipboard_history_text_item_view.h" #include "ash/clipboard/views/clipboard_history_text_item_view.h"
#include "ash/resources/vector_icons/vector_icons.h"
#include "ash/style/ash_color_provider.h"
#include "ash/style/scoped_light_mode_as_default.h"
#include "base/auto_reset.h" #include "base/auto_reset.h"
#include "base/metrics/histogram_macros.h" #include "base/metrics/histogram_macros.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/accessibility/ax_node_data.h" #include "ui/accessibility/ax_node_data.h"
#include "ui/base/clipboard/clipboard_data.h" #include "ui/base/clipboard/clipboard_data.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/image/image_skia_operations.h"
#include "ui/gfx/paint_vector_icon.h"
#include "ui/native_theme/native_theme.h"
#include "ui/views/accessibility/view_accessibility.h" #include "ui/views/accessibility/view_accessibility.h"
#include "ui/views/controls/menu/menu_config.h" #include "ui/views/controls/menu/menu_config.h"
#include "ui/views/controls/menu/menu_item_view.h" #include "ui/views/controls/menu/menu_item_view.h"
...@@ -36,13 +26,6 @@ using Action = ash::ClipboardHistoryUtil::Action; ...@@ -36,13 +26,6 @@ using Action = ash::ClipboardHistoryUtil::Action;
// The insets within the contents view. // The insets within the contents view.
constexpr gfx::Insets kContentsInsets(/*vertical=*/4, /*horizontal=*/16); constexpr gfx::Insets kContentsInsets(/*vertical=*/4, /*horizontal=*/16);
// The size of the `DeleteButton`.
constexpr int kDeleteButtonSizeDip = 16;
// The menu background's color type.
constexpr ash::AshColorProvider::BaseLayerType kMenuBackgroundColorType =
ash::AshColorProvider::BaseLayerType::kOpaque;
} // namespace } // namespace
namespace ash { namespace ash {
...@@ -77,100 +60,6 @@ bool ClipboardHistoryItemView::ContentsView::DoesIntersectRect( ...@@ -77,100 +60,6 @@ bool ClipboardHistoryItemView::ContentsView::DoesIntersectRect(
gfx::ToEnclosedRect(rect_in_delete_button)); gfx::ToEnclosedRect(rect_in_delete_button));
} }
// The view responding to mouse click or gesture tap events.
class ash::ClipboardHistoryItemView::MainButton : public views::Button {
public:
explicit MainButton(ClipboardHistoryItemView* container)
: Button(), container_(container) {
SetFocusBehavior(views::View::FocusBehavior::ALWAYS);
// Let the parent handle accessibility features.
GetViewAccessibility().OverrideIsIgnored(/*value=*/true);
}
MainButton(const MainButton& rhs) = delete;
MainButton& operator=(const MainButton& rhs) = delete;
~MainButton() override = default;
private:
// views::Button:
void OnThemeChanged() override {
views::Button::OnThemeChanged();
SchedulePaint();
}
const char* GetClassName() const override { return "MainButton"; }
void OnGestureEvent(ui::GestureEvent* event) override {
// Give `container_` a chance to handle `event`.
container_->MaybeHandleGestureEventFromMainButton(event);
if (event->handled())
return;
views::Button::OnGestureEvent(event);
// Prevent the menu controller from handling gesture events. The menu
// controller may bring side-effects such as canceling the item selection.
event->SetHandled();
}
void PaintButtonContents(gfx::Canvas* canvas) override {
if (!container_->ShouldHighlight())
return;
// Use the light mode as default because the light mode is the default mode
// of the native theme which decides the context menu's background color.
// TODO(andrewxu): remove this line after https://crbug.com/1143009 is
// fixed.
ScopedLightModeAsDefault scoped_light_mode_as_default;
// Highlight the background when the menu item is selected or pressed.
cc::PaintFlags flags;
flags.setAntiAlias(true);
const auto* color_provider = AshColorProvider::Get();
const AshColorProvider::RippleAttributes ripple_attributes =
color_provider->GetRippleAttributes(
color_provider->GetBaseLayerColor(kMenuBackgroundColorType));
flags.setColor(SkColorSetA(ripple_attributes.base_color,
ripple_attributes.highlight_opacity * 0xFF));
flags.setStyle(cc::PaintFlags::kFill_Style);
canvas->DrawRect(GetLocalBounds(), flags);
}
// The parent view.
ash::ClipboardHistoryItemView* const container_;
};
ClipboardHistoryItemView::DeleteButton::DeleteButton(
ClipboardHistoryItemView* listener)
: views::ImageButton(base::BindRepeating(
[](ClipboardHistoryItemView* item_view, const ui::Event& event) {
item_view->Activate(Action::kDelete, event.flags());
},
base::Unretained(listener))) {
SetFocusBehavior(FocusBehavior::ACCESSIBLE_ONLY);
SetAccessibleName(base::ASCIIToUTF16(std::string(GetClassName())));
SetImageHorizontalAlignment(views::ImageButton::ALIGN_CENTER);
SetImageVerticalAlignment(views::ImageButton::ALIGN_MIDDLE);
SetPreferredSize(gfx::Size(kDeleteButtonSizeDip, kDeleteButtonSizeDip));
}
ClipboardHistoryItemView::DeleteButton::~DeleteButton() = default;
const char* ClipboardHistoryItemView::DeleteButton::GetClassName() const {
return "DeleteButton";
}
void ClipboardHistoryItemView::DeleteButton::OnThemeChanged() {
// Use the light mode as default because the light mode is the default mode of
// the native theme which decides the context menu's background color.
// TODO(andrewxu): remove this line after https://crbug.com/1143009 is fixed.
ScopedLightModeAsDefault scoped_light_mode_as_default;
views::ImageButton::OnThemeChanged();
AshColorProvider::Get()->DecorateCloseButton(this, kDeleteButtonSizeDip,
kCloseButtonIcon);
}
// static // static
std::unique_ptr<ClipboardHistoryItemView> std::unique_ptr<ClipboardHistoryItemView>
ClipboardHistoryItemView::CreateFromClipboardHistoryItem( ClipboardHistoryItemView::CreateFromClipboardHistoryItem(
...@@ -200,53 +89,6 @@ ClipboardHistoryItemView::ClipboardHistoryItemView( ...@@ -200,53 +89,6 @@ ClipboardHistoryItemView::ClipboardHistoryItemView(
views::MenuItemView* container) views::MenuItemView* container)
: clipboard_history_item_(clipboard_history_item), container_(container) {} : clipboard_history_item_(clipboard_history_item), container_(container) {}
void ClipboardHistoryItemView::Init() {
SetFocusBehavior(views::View::FocusBehavior::ACCESSIBLE_ONLY);
GetViewAccessibility().OverrideRole(ax::mojom::Role::kMenuItem);
SetLayoutManager(std::make_unique<views::FillLayout>());
// Ensures that MainButton is below any other child views.
main_button_ = AddChildView(std::make_unique<MainButton>(this));
main_button_->SetCallback(base::BindRepeating(
[](ClipboardHistoryItemView* item, const ui::Event& event) {
// Note that the callback may be triggered through the ENTER key when
// the delete button is under the pseudo focus. Because the delete
// button is not hot-tracked by the menu controller. Meanwhile, the menu
// controller always sends the key event to the hot-tracked view.
// TODO(https://crbug.com/1144994): Modify this part after the clipboard
// history menu code is refactored.
// When an item view is under gesture tap, it may be not under pseudo
// focus yet.
if (event.type() == ui::ET_GESTURE_TAP)
item->pseudo_focus_ = PseudoFocus::kMainButton;
item->Activate(item->CalculateActionForMainButtonClick(),
event.flags());
},
base::Unretained(this)));
contents_view_ = AddChildView(CreateContentsView());
subscription_ = container_->AddSelectedChangedCallback(base::BindRepeating(
&ClipboardHistoryItemView::OnSelectionChanged, base::Unretained(this)));
}
void ClipboardHistoryItemView::OnSelectionChanged() {
if (!container_->IsSelected()) {
SetPseudoFocus(PseudoFocus::kEmpty);
return;
}
// If the pseudo focus is moved from another item view via focus traversal,
// `pseudo_focus_` is already up to date.
if (pseudo_focus_ != PseudoFocus::kEmpty)
return;
InitiatePseudoFocus(/*reverse=*/false);
}
bool ClipboardHistoryItemView::AdvancePseudoFocus(bool reverse) { bool ClipboardHistoryItemView::AdvancePseudoFocus(bool reverse) {
if (pseudo_focus_ == PseudoFocus::kEmpty) { if (pseudo_focus_ == PseudoFocus::kEmpty) {
InitiatePseudoFocus(reverse); InitiatePseudoFocus(reverse);
...@@ -283,6 +125,101 @@ bool ClipboardHistoryItemView::AdvancePseudoFocus(bool reverse) { ...@@ -283,6 +125,101 @@ bool ClipboardHistoryItemView::AdvancePseudoFocus(bool reverse) {
return true; return true;
} }
void ClipboardHistoryItemView::HandleDeleteButtonPressEvent(
const ui::Event& event) {
Activate(Action::kDelete, event.flags());
}
void ClipboardHistoryItemView::HandleMainButtonPressEvent(
const ui::Event& event) {
// Note that the callback may be triggered through the ENTER key when
// the delete button is under the pseudo focus. Because the delete
// button is not hot-tracked by the menu controller. Meanwhile, the menu
// controller always sends the key event to the hot-tracked view.
// TODO(https://crbug.com/1144994): Modify this part after the clipboard
// history menu code is refactored.
// When an item view is under gesture tap, it may be not under pseudo
// focus yet.
if (event.type() == ui::ET_GESTURE_TAP)
pseudo_focus_ = PseudoFocus::kMainButton;
Activate(CalculateActionForMainButtonClick(), event.flags());
}
void ClipboardHistoryItemView::Init() {
SetFocusBehavior(views::View::FocusBehavior::ACCESSIBLE_ONLY);
GetViewAccessibility().OverrideRole(ax::mojom::Role::kMenuItem);
SetLayoutManager(std::make_unique<views::FillLayout>());
// Ensures that MainButton is below any other child views.
main_button_ =
AddChildView(std::make_unique<ClipboardHistoryMainButton>(this));
contents_view_ = AddChildView(CreateContentsView());
subscription_ = container_->AddSelectedChangedCallback(base::BindRepeating(
&ClipboardHistoryItemView::OnSelectionChanged, base::Unretained(this)));
}
void ClipboardHistoryItemView::MaybeHandleGestureEventFromMainButton(
ui::GestureEvent* event) {
// `event` is always handled here if the menu item view is under the gesture
// long press. It prevents other event handlers from introducing side effects.
// For example, if `main_button_` handles the ui::ET_GESTURE_END event,
// `main_button_`'s state will be reset. However, `main_button_` is expected
// to be at the "hovered" state when the menu item is selected.
if (under_gesture_long_press_) {
DCHECK_NE(ui::ET_GESTURE_LONG_PRESS, event->type());
if (event->type() == ui::ET_GESTURE_END)
under_gesture_long_press_ = false;
event->SetHandled();
return;
}
if (event->type() == ui::ET_GESTURE_LONG_PRESS) {
under_gesture_long_press_ = true;
switch (pseudo_focus_) {
case PseudoFocus::kEmpty:
// Select the menu item if it is not selected yet.
Activate(Action::kSelect, event->flags());
break;
case PseudoFocus::kMainButton: {
// The menu item is already selected so show the delete button if the
// button is hidden.
views::View* delete_button = contents_view_->delete_button();
if (!delete_button->GetVisible())
delete_button->SetVisible(true);
break;
}
case PseudoFocus::kDeleteButton:
// The delete button already shows, so do nothing.
DCHECK(contents_view_->delete_button()->GetVisible());
break;
case PseudoFocus::kMaxValue:
NOTREACHED();
break;
}
event->SetHandled();
}
}
void ClipboardHistoryItemView::OnSelectionChanged() {
if (!container_->IsSelected()) {
SetPseudoFocus(PseudoFocus::kEmpty);
return;
}
// If the pseudo focus is moved from another item view via focus traversal,
// `pseudo_focus_` is already up to date.
if (pseudo_focus_ != PseudoFocus::kEmpty)
return;
InitiatePseudoFocus(/*reverse=*/false);
}
void ClipboardHistoryItemView::RecordButtonPressedHistogram() const { void ClipboardHistoryItemView::RecordButtonPressedHistogram() const {
switch (action_) { switch (action_) {
case Action::kDelete: case Action::kDelete:
...@@ -316,7 +253,8 @@ void ClipboardHistoryItemView::GetAccessibleNodeData(ui::AXNodeData* data) { ...@@ -316,7 +253,8 @@ void ClipboardHistoryItemView::GetAccessibleNodeData(ui::AXNodeData* data) {
} }
void ClipboardHistoryItemView::Activate(Action action, int event_flags) { void ClipboardHistoryItemView::Activate(Action action, int event_flags) {
DCHECK(Action::kEmpty == action_ && action_ != action); DCHECK_EQ(Action::kEmpty, action_);
DCHECK_NE(action_, action);
base::AutoReset<Action> action_to_take(&action_, action); base::AutoReset<Action> action_to_take(&action_, action);
RecordButtonPressedHistogram(); RecordButtonPressedHistogram();
...@@ -374,7 +312,7 @@ void ClipboardHistoryItemView::SetPseudoFocus(PseudoFocus new_pseudo_focus) { ...@@ -374,7 +312,7 @@ void ClipboardHistoryItemView::SetPseudoFocus(PseudoFocus new_pseudo_focus) {
pseudo_focus_ = new_pseudo_focus; pseudo_focus_ = new_pseudo_focus;
contents_view_->delete_button()->SetVisible(ShouldShowDeleteButton()); contents_view_->delete_button()->SetVisible(ShouldShowDeleteButton());
main_button_->SchedulePaint(); main_button_->SetShouldHighlight(ShouldHighlight());
switch (pseudo_focus_) { switch (pseudo_focus_) {
case PseudoFocus::kEmpty: case PseudoFocus::kEmpty:
break; break;
...@@ -392,47 +330,4 @@ void ClipboardHistoryItemView::SetPseudoFocus(PseudoFocus new_pseudo_focus) { ...@@ -392,47 +330,4 @@ void ClipboardHistoryItemView::SetPseudoFocus(PseudoFocus new_pseudo_focus) {
} }
} }
void ClipboardHistoryItemView::MaybeHandleGestureEventFromMainButton(
ui::GestureEvent* event) {
// `event` is always handled here if the menu item view is under the gesture
// long press. It prevents other event handlers from introducing side effects.
// For example, if `main_button_` handles the ui::ET_GESTURE_END event,
// `main_button_`'s state will be reset. However, `main_button_` is expected
// to be at the "hovered" state when the menu item is selected.
if (under_gesture_long_press_) {
DCHECK_NE(ui::ET_GESTURE_LONG_PRESS, event->type());
if (event->type() == ui::ET_GESTURE_END)
under_gesture_long_press_ = false;
event->SetHandled();
return;
}
if (event->type() == ui::ET_GESTURE_LONG_PRESS) {
under_gesture_long_press_ = true;
switch (pseudo_focus_) {
case PseudoFocus::kEmpty:
// Select the menu item if it is not selected yet.
Activate(Action::kSelect, event->flags());
break;
case PseudoFocus::kMainButton: {
// The menu item is already selected so show the delete button if the
// button is hidden.
views::View* delete_button = contents_view_->delete_button();
if (!delete_button->GetVisible())
delete_button->SetVisible(true);
break;
}
case PseudoFocus::kDeleteButton:
// The delete button already shows, so do nothing.
DCHECK(contents_view_->delete_button()->GetVisible());
break;
case PseudoFocus::kMaxValue:
NOTREACHED();
break;
}
event->SetHandled();
}
}
} // namespace ash } // namespace ash
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
#define ASH_CLIPBOARD_VIEWS_CLIPBOARD_HISTORY_ITEM_VIEW_H_ #define ASH_CLIPBOARD_VIEWS_CLIPBOARD_HISTORY_ITEM_VIEW_H_
#include "ash/clipboard/clipboard_history_util.h" #include "ash/clipboard/clipboard_history_util.h"
#include "ui/views/controls/button/image_button.h" #include "ui/views/view.h"
#include "ui/views/view_targeter_delegate.h" #include "ui/views/view_targeter_delegate.h"
namespace views { namespace views {
...@@ -14,7 +14,9 @@ class MenuItemView; ...@@ -14,7 +14,9 @@ class MenuItemView;
} // namespace views } // namespace views
namespace ash { namespace ash {
class ClipboardHistoryDeleteButton;
class ClipboardHistoryItem; class ClipboardHistoryItem;
class ClipboardHistoryMainButton;
class ClipboardHistoryResourceManager; class ClipboardHistoryResourceManager;
// The base class for menu items of the clipboard history menu. // The base class for menu items of the clipboard history menu.
...@@ -31,43 +33,34 @@ class ClipboardHistoryItemView : public views::View { ...@@ -31,43 +33,34 @@ class ClipboardHistoryItemView : public views::View {
delete; delete;
~ClipboardHistoryItemView() override; ~ClipboardHistoryItemView() override;
// Advances the pseudo focus (backward if reverse is true). Returns whether
// the view still keeps the pseudo focus.
bool AdvancePseudoFocus(bool reverse);
void HandleDeleteButtonPressEvent(const ui::Event& event);
void HandleMainButtonPressEvent(const ui::Event& event);
// Initializes the menu item. // Initializes the menu item.
void Init(); void Init();
// Attempts to handle the gesture event redirected from `main_button_`.
void MaybeHandleGestureEventFromMainButton(ui::GestureEvent* event);
// Called when the selection state has changed. // Called when the selection state has changed.
void OnSelectionChanged(); void OnSelectionChanged();
// Advances the pseudo focus (backward if reverse is true). Returns whether
// the view still keeps the pseudo focus.
bool AdvancePseudoFocus(bool reverse);
ClipboardHistoryUtil::Action action() const { return action_; } ClipboardHistoryUtil::Action action() const { return action_; }
views::View* delete_button_for_test() { ClipboardHistoryDeleteButton* delete_button_for_test() {
return contents_view_->delete_button(); return contents_view_->delete_button();
} }
const views::View* delete_button_for_test() const { const ClipboardHistoryDeleteButton* delete_button_for_test() const {
return contents_view_->delete_button(); return contents_view_->delete_button();
} }
protected: protected:
class MainButton;
// The button to delete the menu item and its corresponding clipboard data.
class DeleteButton : public views::ImageButton {
public:
explicit DeleteButton(ClipboardHistoryItemView* listener);
DeleteButton(const DeleteButton& rhs) = delete;
DeleteButton& operator=(const DeleteButton& rhs) = delete;
~DeleteButton() override;
private:
// views::ImageButton:
const char* GetClassName() const override;
void OnThemeChanged() override;
};
// Used by subclasses to draw contents, such as text or bitmaps. // Used by subclasses to draw contents, such as text or bitmaps.
class ContentsView : public views::View, public views::ViewTargeterDelegate { class ContentsView : public views::View, public views::ViewTargeterDelegate {
public: public:
...@@ -79,11 +72,13 @@ class ClipboardHistoryItemView : public views::View { ...@@ -79,11 +72,13 @@ class ClipboardHistoryItemView : public views::View {
// Install DeleteButton on the contents view. // Install DeleteButton on the contents view.
void InstallDeleteButton(); void InstallDeleteButton();
views::View* delete_button() { return delete_button_; } ClipboardHistoryDeleteButton* delete_button() { return delete_button_; }
const views::View* delete_button() const { return delete_button_; } const ClipboardHistoryDeleteButton* delete_button() const {
return delete_button_;
}
protected: protected:
virtual DeleteButton* CreateDeleteButton() = 0; virtual ClipboardHistoryDeleteButton* CreateDeleteButton() = 0;
ClipboardHistoryItemView* container() { return container_; } ClipboardHistoryItemView* container() { return container_; }
...@@ -96,7 +91,7 @@ class ClipboardHistoryItemView : public views::View { ...@@ -96,7 +91,7 @@ class ClipboardHistoryItemView : public views::View {
const gfx::Rect& rect) const override; const gfx::Rect& rect) const override;
// Owned by the view hierarchy. // Owned by the view hierarchy.
DeleteButton* delete_button_ = nullptr; ClipboardHistoryDeleteButton* delete_button_ = nullptr;
// The parent of ContentsView. // The parent of ContentsView.
ClipboardHistoryItemView* const container_; ClipboardHistoryItemView* const container_;
...@@ -163,9 +158,6 @@ class ClipboardHistoryItemView : public views::View { ...@@ -163,9 +158,6 @@ class ClipboardHistoryItemView : public views::View {
// Updates `pseudo_focus_` and children visibility. // Updates `pseudo_focus_` and children visibility.
void SetPseudoFocus(PseudoFocus new_pseudo_focus); void SetPseudoFocus(PseudoFocus new_pseudo_focus);
// Attempts to handle the gesture event redirected from `main_button_`.
void MaybeHandleGestureEventFromMainButton(ui::GestureEvent* event);
// Owned by ClipboardHistoryMenuModelAdapter. // Owned by ClipboardHistoryMenuModelAdapter.
const ClipboardHistoryItem* const clipboard_history_item_; const ClipboardHistoryItem* const clipboard_history_item_;
...@@ -173,7 +165,7 @@ class ClipboardHistoryItemView : public views::View { ...@@ -173,7 +165,7 @@ class ClipboardHistoryItemView : public views::View {
ContentsView* contents_view_ = nullptr; ContentsView* contents_view_ = nullptr;
MainButton* main_button_ = nullptr; ClipboardHistoryMainButton* main_button_ = nullptr;
PseudoFocus pseudo_focus_ = PseudoFocus::kEmpty; PseudoFocus pseudo_focus_ = PseudoFocus::kEmpty;
......
// Copyright 2020 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/clipboard/views/clipboard_history_main_button.h"
#include "ash/clipboard/views/clipboard_history_item_view.h"
#include "ash/style/ash_color_provider.h"
#include "ash/style/scoped_light_mode_as_default.h"
#include "ui/gfx/canvas.h"
#include "ui/views/accessibility/view_accessibility.h"
namespace ash {
namespace {
// The menu background's color type.
constexpr ash::AshColorProvider::BaseLayerType kMenuBackgroundColorType =
ash::AshColorProvider::BaseLayerType::kOpaque;
} // namespace
ClipboardHistoryMainButton::ClipboardHistoryMainButton(
ClipboardHistoryItemView* container)
: Button(base::BindRepeating(
[](ClipboardHistoryItemView* item, const ui::Event& event) {
item->HandleMainButtonPressEvent(event);
},
base::Unretained(container))),
container_(container) {
SetFocusBehavior(views::View::FocusBehavior::ALWAYS);
// Let the parent handle accessibility features.
GetViewAccessibility().OverrideIsIgnored(/*value=*/true);
}
ClipboardHistoryMainButton::~ClipboardHistoryMainButton() = default;
void ClipboardHistoryMainButton::SetShouldHighlight(bool should_highlight) {
if (should_highlight_ == should_highlight)
return;
should_highlight_ = should_highlight;
SchedulePaint();
}
const char* ClipboardHistoryMainButton::GetClassName() const {
return "ClipboardHistoryMainButton";
}
void ClipboardHistoryMainButton::OnThemeChanged() {
views::Button::OnThemeChanged();
SchedulePaint();
}
void ClipboardHistoryMainButton::OnGestureEvent(ui::GestureEvent* event) {
// Give `container_` a chance to handle `event`.
container_->MaybeHandleGestureEventFromMainButton(event);
if (event->handled())
return;
views::Button::OnGestureEvent(event);
// Prevent the menu controller from handling gesture events. The menu
// controller may bring side-effects such as canceling the item selection.
event->SetHandled();
}
void ClipboardHistoryMainButton::PaintButtonContents(gfx::Canvas* canvas) {
if (!should_highlight_)
return;
// Use the light mode as default because the light mode is the default mode
// of the native theme which decides the context menu's background color.
// TODO(andrewxu): remove this line after https://crbug.com/1143009 is
// fixed.
ScopedLightModeAsDefault scoped_light_mode_as_default;
// Highlight the background when the menu item is selected or pressed.
cc::PaintFlags flags;
flags.setAntiAlias(true);
const auto* color_provider = AshColorProvider::Get();
const AshColorProvider::RippleAttributes ripple_attributes =
color_provider->GetRippleAttributes(
color_provider->GetBaseLayerColor(kMenuBackgroundColorType));
flags.setColor(SkColorSetA(ripple_attributes.base_color,
ripple_attributes.highlight_opacity * 0xFF));
flags.setStyle(cc::PaintFlags::kFill_Style);
canvas->DrawRect(GetLocalBounds(), flags);
}
} // namespace ash
// Copyright 2020 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_CLIPBOARD_VIEWS_CLIPBOARD_HISTORY_MAIN_BUTTON_H_
#define ASH_CLIPBOARD_VIEWS_CLIPBOARD_HISTORY_MAIN_BUTTON_H_
#include "ui/views/controls/button/button.h"
namespace ash {
class ClipboardHistoryItemView;
// The view responding to mouse click or gesture tap events.
class ClipboardHistoryMainButton : public views::Button {
public:
explicit ClipboardHistoryMainButton(ClipboardHistoryItemView* container);
ClipboardHistoryMainButton(const ClipboardHistoryMainButton& rhs) = delete;
ClipboardHistoryMainButton& operator=(const ClipboardHistoryMainButton& rhs) =
delete;
~ClipboardHistoryMainButton() override;
void SetShouldHighlight(bool should_highlight);
private:
// views::Button:
const char* GetClassName() const override;
void OnThemeChanged() override;
void OnGestureEvent(ui::GestureEvent* event) override;
void PaintButtonContents(gfx::Canvas* canvas) override;
// The parent view.
ClipboardHistoryItemView* const container_;
// Indicates whether the view should be highlighted.
bool should_highlight_ = false;
};
} // namespace ash
#endif // ASH_CLIPBOARD_VIEWS_CLIPBOARD_HISTORY_MAIN_BUTTON_H_
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "ash/clipboard/clipboard_history_controller_impl.h" #include "ash/clipboard/clipboard_history_controller_impl.h"
#include "ash/clipboard/clipboard_history_resource_manager.h" #include "ash/clipboard/clipboard_history_resource_manager.h"
#include "ash/clipboard/clipboard_history_util.h" #include "ash/clipboard/clipboard_history_util.h"
#include "ash/clipboard/views/clipboard_history_delete_button.h"
#include "ash/clipboard/views/clipboard_history_label.h" #include "ash/clipboard/views/clipboard_history_label.h"
#include "ash/shell.h" #include "ash/shell.h"
#include "base/metrics/histogram_macros.h" #include "base/metrics/histogram_macros.h"
...@@ -48,8 +49,9 @@ class ClipboardHistoryTextItemView::TextContentsView ...@@ -48,8 +49,9 @@ class ClipboardHistoryTextItemView::TextContentsView
private: private:
// ContentsView: // ContentsView:
DeleteButton* CreateDeleteButton() override { ClipboardHistoryDeleteButton* CreateDeleteButton() override {
auto delete_button = std::make_unique<DeleteButton>(container()); auto delete_button =
std::make_unique<ClipboardHistoryDeleteButton>(container());
delete_button->SetVisible(false); delete_button->SetVisible(false);
delete_button->SetProperty(views::kMarginsKey, kDeleteButtonMargins); delete_button->SetProperty(views::kMarginsKey, kDeleteButtonMargins);
return AddChildView(std::move(delete_button)); return AddChildView(std::move(delete_button));
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "ash/clipboard/clipboard_history_controller_impl.h" #include "ash/clipboard/clipboard_history_controller_impl.h"
#include "ash/clipboard/clipboard_history_item.h" #include "ash/clipboard/clipboard_history_item.h"
#include "ash/clipboard/clipboard_history_menu_model_adapter.h" #include "ash/clipboard/clipboard_history_menu_model_adapter.h"
#include "ash/clipboard/views/clipboard_history_delete_button.h"
#include "ash/clipboard/views/clipboard_history_item_view.h" #include "ash/clipboard/views/clipboard_history_item_view.h"
#include "ash/shell.h" #include "ash/shell.h"
#include "base/test/bind.h" #include "base/test/bind.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