Skip to content

Commit

Permalink
Desk Templates: Create delete button
Browse files Browse the repository at this point in the history
This CL adds in the UI elements for the delete button, as well as the
show on hover functionality by having the GridView listen for mouse and
touch events, then updating the visibility of the delete button. A
PreTargetHandler was required to ensure that events are not accidentally
captured by other views. Actual delete functionality (hooking it up to
DeskModel) and style will be added in later.

Bug: 1255300
Test: manual
Change-Id: I3202c7c3c4377d94940ecc8b1d387f914eb41e76
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3200479
Commit-Queue: Richard Chui <richui@chromium.org>
Reviewed-by: Sammie Quon <sammiequon@chromium.org>
Cr-Commit-Position: refs/heads/main@{#930645}
  • Loading branch information
Richard Chui authored and Chromium LUCI CQ committed Oct 12, 2021
1 parent be0664d commit b414fa4
Show file tree
Hide file tree
Showing 9 changed files with 229 additions and 36 deletions.
2 changes: 2 additions & 0 deletions ash/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -1646,6 +1646,8 @@ component("ash") {
"wm/desks/root_window_desk_switch_animator.h",
"wm/desks/scroll_arrow_button.cc",
"wm/desks/scroll_arrow_button.h",
"wm/desks/templates/desks_templates_delete_button.cc",
"wm/desks/templates/desks_templates_delete_button.h",
"wm/desks/templates/desks_templates_dialog_controller.cc",
"wm/desks/templates/desks_templates_dialog_controller.h",
"wm/desks/templates/desks_templates_grid_view.cc",
Expand Down
33 changes: 33 additions & 0 deletions ash/wm/desks/templates/desks_templates_delete_button.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright 2021 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/wm/desks/templates/desks_templates_delete_button.h"

#include "ash/resources/vector_icons/vector_icons.h"
#include "ash/style/element_style.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/metadata/metadata_impl_macros.h"
#include "ui/strings/grit/ui_strings.h"

namespace ash {

DesksTemplatesDeleteButton::DesksTemplatesDeleteButton() {
views::Builder<DesksTemplatesDeleteButton>(this)
.SetImageHorizontalAlignment(views::ImageButton::ALIGN_CENTER)
.SetImageVerticalAlignment(views::ImageButton::ALIGN_MIDDLE)
.SetTooltipText(l10n_util::GetStringUTF16(IDS_APP_DELETE))
.BuildChildren();
}

DesksTemplatesDeleteButton::~DesksTemplatesDeleteButton() = default;

void DesksTemplatesDeleteButton::OnThemeChanged() {
views::ImageButton::OnThemeChanged();
element_style::DecorateMediumCloseButton(this, kTrashCanIcon);
}

BEGIN_METADATA(DesksTemplatesDeleteButton, views::ImageButton)
END_METADATA

} // namespace ash
38 changes: 38 additions & 0 deletions ash/wm/desks/templates/desks_templates_delete_button.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright 2021 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_WM_DESKS_TEMPLATES_DESKS_TEMPLATES_DELETE_BUTTON_H_
#define ASH_WM_DESKS_TEMPLATES_DESKS_TEMPLATES_DELETE_BUTTON_H_

#include "ui/base/metadata/metadata_header_macros.h"
#include "ui/views/controls/button/image_button.h"

namespace ash {

// A button view that shows up when hovering over the associated grid item.
// Allows the user to delete the template.
class DesksTemplatesDeleteButton : public views::ImageButton {
public:
METADATA_HEADER(DesksTemplatesDeleteButton);

DesksTemplatesDeleteButton();
DesksTemplatesDeleteButton(const DesksTemplatesDeleteButton&) = delete;
DesksTemplatesDeleteButton& operator=(const DesksTemplatesDeleteButton&) =
delete;
~DesksTemplatesDeleteButton() override;

// views::ImageButton:
void OnThemeChanged() override;
};

BEGIN_VIEW_BUILDER(/* no export */,
DesksTemplatesDeleteButton,
views::ImageButton)
END_VIEW_BUILDER

} // namespace ash

DEFINE_VIEW_BUILDER(/* no export */, ash::DesksTemplatesDeleteButton)

#endif // ASH_WM_DESKS_TEMPLATES_DESKS_TEMPLATES_DELETE_BUTTON_H_
47 changes: 44 additions & 3 deletions ash/wm/desks/templates/desks_templates_grid_view.cc
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,11 @@ DesksTemplatesGridView::DesksTemplatesGridView() {
layout->StartRowWithPadding(fixed_size, kColumnSetId, fixed_size,
kGridPaddingDp);
}

for (int j = 0; j < kNumColumns; ++j)
layout->AddView(std::make_unique<DesksTemplatesItemView>());
for (int j = 0; j < kNumColumns; ++j) {
DesksTemplatesItemView* grid_item =
layout->AddView(std::make_unique<DesksTemplatesItemView>());
grid_items_.push_back(grid_item);
}
}
}

Expand Down Expand Up @@ -100,6 +102,45 @@ views::UniqueWidgetPtr DesksTemplatesGridView::CreateDesksTemplatesGridWidget(
return widget;
}

void DesksTemplatesGridView::OnMouseEvent(ui::MouseEvent* event) {
OnLocatedEvent(event, /*is_touch=*/false);
}

void DesksTemplatesGridView::OnGestureEvent(ui::GestureEvent* event) {
OnLocatedEvent(event, /*is_touch=*/true);
}

void DesksTemplatesGridView::AddedToWidget() {
// Adding a pre-target handler to ensure that events are not accidentally
// captured by the child views. Also, `this` is added as the pre-target
// handler to the window as opposed to `Env` to ensure that we only get events
// that are on this window.
widget_window_ = GetWidget()->GetNativeWindow();
widget_window_->AddPreTargetHandler(this);
}

void DesksTemplatesGridView::RemovedFromWidget() {
DCHECK(widget_window_);
widget_window_->RemovePreTargetHandler(this);
widget_window_ = nullptr;
}

void DesksTemplatesGridView::OnLocatedEvent(ui::LocatedEvent* event,
bool is_touch) {
switch (event->type()) {
case ui::ET_MOUSE_MOVED:
case ui::ET_MOUSE_ENTERED:
case ui::ET_MOUSE_EXITED:
case ui::ET_GESTURE_LONG_PRESS:
case ui::ET_GESTURE_LONG_TAP:
for (auto* grid_item : grid_items_)
grid_item->UpdateDeleteButtonVisibility();
return;
default:
return;
}
}

BEGIN_METADATA(DesksTemplatesGridView, views::View)
END_METADATA

Expand Down
20 changes: 19 additions & 1 deletion ash/wm/desks/templates/desks_templates_grid_view.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@

namespace ash {

class DesksTemplatesItemView;

// A view that acts as the content view of the desks templates widget.
// TODO(sammiequon): Add details and ASCII.
// TODO(richui): Add details and ASCII.
class DesksTemplatesGridView : public views::View {
public:
METADATA_HEADER(DesksTemplatesGridView);
Expand All @@ -29,6 +31,22 @@ class DesksTemplatesGridView : public views::View {
static views::UniqueWidgetPtr CreateDesksTemplatesGridWidget(
aura::Window* root,
const gfx::Rect& grid_bounds);

// views::View:
void OnMouseEvent(ui::MouseEvent* event) override;
void OnGestureEvent(ui::GestureEvent* event) override;
void AddedToWidget() override;
void RemovedFromWidget() override;

private:
// Helper to unify mouse/touch events.
void OnLocatedEvent(ui::LocatedEvent* event, bool is_touch);

// The views representing templates. They're owned by views hierarchy.
std::vector<DesksTemplatesItemView*> grid_items_;

// The underlying window of the templates grid widget.
aura::Window* widget_window_ = nullptr;
};

} // namespace ash
Expand Down
78 changes: 60 additions & 18 deletions ash/wm/desks/templates/desks_templates_item_view.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,13 @@

#include "ash/wm/desks/templates/desks_templates_item_view.h"

#include "ash/accessibility/accessibility_controller_impl.h"
#include "ash/shell.h"
#include "ash/wm/desks/templates/desks_templates_delete_button.h"
#include "base/notreached.h"
#include "ui/base/metadata/metadata_impl_macros.h"
#include "ui/views/border.h"
#include "ui/views/layout/box_layout_view.h"

namespace ash {

Expand All @@ -18,42 +23,74 @@ constexpr gfx::Size kViewSize(250, 40);
constexpr gfx::Size kPreferredSize(250, 150);
constexpr int kIconSpacingDp = 10;
constexpr gfx::Size kPreviewIconSize(40, 40);
constexpr int kDeleteButtonMargin = 8;
constexpr int kDeleteButtonSize = 24;

} // namespace

DesksTemplatesItemView::DesksTemplatesItemView() {
// TODO(richui): Remove all the borders. It is only used for visualizing
// bounds while it is a placeholder.
auto delete_button_callback = base::BindRepeating(
&DesksTemplatesItemView::OnDeleteButtonPressed, base::Unretained(this));

views::View* spacer;
views::BoxLayoutView* container;
views::Builder<DesksTemplatesItemView>(this)
.SetOrientation(views::BoxLayout::Orientation::kVertical)
.SetCrossAxisAlignment(views::BoxLayout::CrossAxisAlignment::kStart)
.SetPreferredSize(kPreferredSize)
.SetUseDefaultFillLayout(true)
.SetBorder(views::CreateSolidBorder(/*thickness=*/2, SK_ColorDKGRAY))
.AddChildren(
views::Builder<views::View>()
.CopyAddressTo(&name_view_)
.SetPreferredSize(kViewSize)
.SetBorder(views::CreateSolidBorder(
/*thickness=*/2, SK_ColorGRAY)),
views::Builder<views::View>()
.CopyAddressTo(&time_view_)
.SetPreferredSize(kViewSize)
.SetBorder(views::CreateSolidBorder(
/*thickness=*/2, SK_ColorGRAY)),
views::Builder<views::View>().CopyAddressTo(&spacer),
views::Builder<views::BoxLayoutView>()
.CopyAddressTo(&preview_view_)
.SetOrientation(views::BoxLayout::Orientation::kHorizontal)
.SetBetweenChildSpacing(kIconSpacingDp))
.CopyAddressTo(&container)
.SetOrientation(views::BoxLayout::Orientation::kVertical)
.SetCrossAxisAlignment(
views::BoxLayout::CrossAxisAlignment::kStart)
.AddChildren(views::Builder<views::View>()
.CopyAddressTo(&name_view_)
.SetPreferredSize(kViewSize)
.SetBorder(views::CreateSolidBorder(
/*thickness=*/2, SK_ColorGRAY)),
views::Builder<views::View>()
.CopyAddressTo(&time_view_)
.SetPreferredSize(kViewSize)
.SetBorder(views::CreateSolidBorder(
/*thickness=*/2, SK_ColorGRAY)),
views::Builder<views::View>().CopyAddressTo(&spacer),
views::Builder<views::BoxLayoutView>()
.CopyAddressTo(&preview_view_)
.SetOrientation(
views::BoxLayout::Orientation::kHorizontal)
.SetBetweenChildSpacing(kIconSpacingDp)),
views::Builder<DesksTemplatesDeleteButton>()
.CopyAddressTo(&delete_button_)
.SetCallback(delete_button_callback))
.BuildChildren();

SetFlexForView(spacer, 1);
container->SetFlexForView(spacer, 1);
UpdateDeleteButtonVisibility();
SetIcons();
}

DesksTemplatesItemView::~DesksTemplatesItemView() = default;

void DesksTemplatesItemView::UpdateDeleteButtonVisibility() {
// For switch access, setting the delete button to visible allows users to
// navigate to it.
// TODO(richui): update `force_show_delete_button_` based on touch events.
delete_button_->SetVisible(
(IsMouseHovered() || force_show_delete_button_ ||
Shell::Get()->accessibility_controller()->IsSwitchAccessRunning()));
}

void DesksTemplatesItemView::Layout() {
views::View::Layout();

delete_button_->SetBoundsRect(
gfx::Rect(width() - kDeleteButtonSize - kDeleteButtonMargin,
kDeleteButtonMargin, kDeleteButtonSize, kDeleteButtonSize));
}

void DesksTemplatesItemView::SetIcons() {
for (int i = 0; i < kMaxIcons; ++i) {
preview_view_->AddChildView(views::Builder<views::View>()
Expand All @@ -64,7 +101,12 @@ void DesksTemplatesItemView::SetIcons() {
}
}

BEGIN_METADATA(DesksTemplatesItemView, views::BoxLayoutView)
void DesksTemplatesItemView::OnDeleteButtonPressed() {
// TODO(richui): Hook this up to the presenter.
NOTIMPLEMENTED();
}

BEGIN_METADATA(DesksTemplatesItemView, views::View)
END_METADATA

} // namespace ash
28 changes: 23 additions & 5 deletions ash/wm/desks/templates/desks_templates_item_view.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,19 @@
#define ASH_WM_DESKS_TEMPLATES_DESKS_TEMPLATES_ITEM_VIEW_H_

#include "ui/base/metadata/metadata_header_macros.h"
#include "ui/views/layout/box_layout_view.h"
#include "ui/views/view.h"

namespace views {
class BoxLayoutView;
}

namespace ash {

class DesksTemplatesDeleteButton;

// A view that represents each individual template item in the desks templates
// grid.
class DesksTemplatesItemView : public views::BoxLayoutView {
class DesksTemplatesItemView : public views::View {
public:
METADATA_HEADER(DesksTemplatesItemView);

Expand All @@ -21,19 +27,31 @@ class DesksTemplatesItemView : public views::BoxLayoutView {
DesksTemplatesItemView& operator=(const DesksTemplatesItemView&) = delete;
~DesksTemplatesItemView() override;

// Updates the visibility state of the delete button depending on whether this
// view is mouse hovered, or if switch access is enabled.
void UpdateDeleteButtonVisibility();

// views::View:
void Layout() override;

private:
// TODO(richui): Pass a list of icons as the parameter.
void SetIcons();

void OnDeleteButtonPressed();

// Owned by the views hierarchy.
views::View* name_view_ = nullptr;
views::View* time_view_ = nullptr;
views::BoxLayoutView* preview_view_ = nullptr;
DesksTemplatesDeleteButton* delete_button_ = nullptr;

// We force showing the delete button when `this` is long pressed or tapped
// using touch gestures.
bool force_show_delete_button_ = false;
};

BEGIN_VIEW_BUILDER(/* no export */,
DesksTemplatesItemView,
views::BoxLayoutView)
BEGIN_VIEW_BUILDER(/* no export */, DesksTemplatesItemView, views::View)
END_VIEW_BUILDER

} // namespace ash
Expand Down
17 changes: 9 additions & 8 deletions ash/wm/overview/overview_grid.cc
Original file line number Diff line number Diff line change
Expand Up @@ -463,8 +463,8 @@ void OverviewGrid::Shutdown(OverviewEnterExitType exit_type) {

window_list_.clear();

if (desks_templates_grid_)
desks_templates_grid_->CloseNow();
if (desks_templates_grid_widget_)
desks_templates_grid_widget_->CloseNow();

overview_session_ = nullptr;

Expand Down Expand Up @@ -857,17 +857,18 @@ void OverviewGrid::OnSelectorItemDragStarted(OverviewItem* item) {
}

void OverviewGrid::ShowDesksTemplatesGrid() {
if (!desks_templates_grid_) {
desks_templates_grid_ =
if (!desks_templates_grid_widget_) {
desks_templates_grid_widget_ =
DesksTemplatesGridView::CreateDesksTemplatesGridWidget(
root_window_, GetGridEffectiveBounds());
}

desks_templates_grid_->Show();
desks_templates_grid_widget_->Show();
}

bool OverviewGrid::IsShowingDesksTemplatesGrid() const {
return desks_templates_grid_ && desks_templates_grid_->IsVisible();
return desks_templates_grid_widget_ &&
desks_templates_grid_widget_->IsVisible();
}

void OverviewGrid::UpdateNoWindowsWidget(bool no_items) {
Expand Down Expand Up @@ -1060,8 +1061,8 @@ void OverviewGrid::OnDisplayMetricsChanged() {

UpdateCannotSnapWarningVisibility();

if (desks_templates_grid_)
desks_templates_grid_->SetBounds(GetGridEffectiveBounds());
if (desks_templates_grid_widget_)
desks_templates_grid_widget_->SetBounds(GetGridEffectiveBounds());

// In case of split view mode, the grid bounds and item positions will be
// updated in |OnSplitViewDividerPositionChanged|.
Expand Down
Loading

0 comments on commit b414fa4

Please sign in to comment.