1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
|
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chromeos/ui/frame/multitask_menu/multitask_menu.h"
#include <memory>
#include "base/check.h"
#include "chromeos/ui/base/display_util.h"
#include "chromeos/ui/base/window_properties.h"
#include "chromeos/ui/frame/multitask_menu/float_controller_base.h"
#include "chromeos/ui/frame/multitask_menu/multitask_menu_view.h"
#include "chromeos/ui/wm/window_util.h"
#include "ui/base/metadata/metadata_impl_macros.h"
#include "ui/base/mojom/dialog_button.mojom.h"
#include "ui/display/screen.h"
#include "ui/display/tablet_state.h"
#include "ui/views/layout/table_layout.h"
namespace chromeos {
namespace {
constexpr int kMultitaskMenuBubbleCornerRadius = 8;
// Padding between the edges of the menu and the elements.
constexpr int kPaddingWide = 12;
// Padding between the elements.
constexpr int kPaddingNarrow = 8;
} // namespace
MultitaskMenu::MultitaskMenu(views::View* anchor,
views::Widget* parent_widget,
bool close_on_move_out) {
DCHECK(parent_widget);
set_corner_radius(kMultitaskMenuBubbleCornerRadius);
set_close_on_deactivate(true);
set_internal_name("MultitaskMenuBubbleWidget");
set_margins(gfx::Insets());
set_parent_window(parent_widget->GetNativeWindow());
SetAnchorView(anchor);
SetArrow(views::BubbleBorder::Arrow::TOP_CENTER);
SetEnableArrowKeyTraversal(true);
SetButtons(static_cast<int>(ui::mojom::DialogButton::kNone));
SetCanActivate(parent_widget->IsActive());
SetUseDefaultFillLayout(true);
uint8_t buttons = MultitaskMenuView::kFullscreen;
if (SnapController::Get()->CanSnap(parent_window())) {
buttons |= MultitaskMenuView::kHalfSplit;
buttons |= MultitaskMenuView::kPartialSplit;
}
if (chromeos::wm::CanFloatWindow(parent_window())) {
buttons |= MultitaskMenuView::kFloat;
}
// Must be initialized after setting bounds.
multitask_menu_view_ = AddChildView(std::make_unique<MultitaskMenuView>(
parent_window(),
base::BindRepeating(&MultitaskMenu::HideBubble, base::Unretained(this)),
base::BindRepeating(&MultitaskMenu::HideBubble, base::Unretained(this)),
buttons, close_on_move_out ? anchor : nullptr));
multitask_menu_view_->SetLayoutManager(std::make_unique<views::TableLayout>())
->AddPaddingColumn(views::TableLayout::kFixedSize, kPaddingWide)
.AddColumn(views::LayoutAlignment::kCenter,
views::LayoutAlignment::kCenter,
views::TableLayout::kFixedSize,
views::TableLayout::ColumnSize::kUsePreferred, 0, 0)
.AddPaddingColumn(views::TableLayout::kFixedSize, kPaddingNarrow)
.AddColumn(views::LayoutAlignment::kCenter,
views::LayoutAlignment::kCenter,
views::TableLayout::kFixedSize,
views::TableLayout::ColumnSize::kUsePreferred, 0, 0)
.AddPaddingColumn(views::TableLayout::kFixedSize, kPaddingWide)
.AddPaddingRow(views::TableLayout::kFixedSize, kPaddingWide)
.AddRows(1, views::TableLayout::kFixedSize, 0)
.AddPaddingRow(views::TableLayout::kFixedSize, kPaddingNarrow)
.AddRows(1, views::TableLayout::kFixedSize, 0)
.AddPaddingRow(views::TableLayout::kFixedSize, kPaddingWide);
display_observer_.emplace(this);
window_observation_.Observe(parent_widget->GetNativeWindow());
}
MultitaskMenu::~MultitaskMenu() = default;
void MultitaskMenu::HideBubble() {
// Callers of this function are expected to alter the bounds of the parent
// window. Do not animate in this case otherwise the bubble may fade out while
// outside of the parent window's bounds.
views::Widget* widget = GetWidget();
widget->SetVisibilityAnimationTransition(views::Widget::ANIMATE_NONE);
// Destroys `this`.
widget->CloseWithReason(views::Widget::ClosedReason::kUnspecified);
}
base::WeakPtr<MultitaskMenu> MultitaskMenu::GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
void MultitaskMenu::OnDisplayTabletStateChanged(display::TabletState state) {
if (state == display::TabletState::kEnteringTabletMode)
HideBubble();
}
void MultitaskMenu::OnDisplayMetricsChanged(const display::Display& display,
uint32_t changed_metrics) {
// Ignore changes to displays that aren't showing the menu.
if (display.id() !=
display::Screen::GetScreen()
->GetDisplayNearestView(GetWidget()->GetNativeWindow())
.id()) {
return;
}
if (changed_metrics & display::DisplayObserver::DISPLAY_METRIC_ROTATION)
HideBubble();
}
void MultitaskMenu::OnWindowPropertyChanged(aura::Window* window,
const void* key,
intptr_t old) {
if (key == kIsShowingInOverviewKey) {
HideBubble();
}
}
void MultitaskMenu::OnWindowDestroying(aura::Window* window) {
window_observation_.Reset();
}
BEGIN_METADATA(MultitaskMenu)
END_METADATA
} // namespace chromeos
|