123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- // 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/app_list/views/search_result_page_anchored_dialog.h"
- #include <utility>
- #include "ash/constants/ash_features.h"
- #include "ui/compositor/layer.h"
- #include "ui/gfx/geometry/point.h"
- #include "ui/gfx/geometry/rect.h"
- #include "ui/gfx/geometry/size.h"
- #include "ui/gfx/geometry/transform.h"
- #include "ui/views/view.h"
- #include "ui/views/window/dialog_delegate.h"
- #include "ui/views/window/non_client_view.h"
- #include "ui/wm/core/coordinate_conversion.h"
- namespace ash {
- namespace {
- // The intended offset the dialog should have from the top of the anchor view
- // bounds.
- constexpr int kDialogVerticalMargin = 32;
- } // namespace
- SearchResultPageAnchoredDialog::SearchResultPageAnchoredDialog(
- std::unique_ptr<views::WidgetDelegate> dialog,
- views::View* host_view,
- base::OnceClosure callback)
- : host_view_(host_view), callback_(std::move(callback)) {
- DCHECK(!dialog->GetWidget());
- views::Widget* const parent = host_view_->GetWidget();
- widget_ = new views::Widget();
- views::Widget::InitParams params;
- // Pre-productivity launcher uses DialogDelegateView for the dialog, while the
- // productivity launcher expects a frameless widget.
- if (features::IsProductivityLauncherEnabled()) {
- params.type = views::Widget::InitParams::TYPE_WINDOW_FRAMELESS;
- params.layer_type = ui::LAYER_NOT_DRAWN;
- params.parent = parent->GetNativeWindow();
- params.delegate = dialog.release();
- } else {
- params = views::DialogDelegateView::GetDialogWidgetInitParams(
- dialog.release(), parent->GetNativeWindow(), parent->GetNativeWindow(),
- gfx::Rect());
- }
- widget_->Init(std::move(params));
- // The |dialog| ownership is passed to the window hierarchy.
- widget_observations_.AddObservation(widget_);
- widget_observations_.AddObservation(parent);
- view_observations_.AddObservation(host_view_);
- view_observations_.AddObservation(widget_->GetContentsView());
- }
- SearchResultPageAnchoredDialog::~SearchResultPageAnchoredDialog() {
- view_observations_.RemoveAllObservations();
- widget_observations_.RemoveAllObservations();
- if (widget_)
- widget_->Close();
- }
- void SearchResultPageAnchoredDialog::UpdateBounds() {
- if (!widget_)
- return;
- gfx::Point anchor_point_in_screen(host_view_->width() / 2, 0);
- views::View::ConvertPointToScreen(host_view_, &anchor_point_in_screen);
- const int offset_for_frame_insets =
- widget_->non_client_view() && widget_->non_client_view()->frame_view()
- ? widget_->non_client_view()->frame_view()->GetInsets().top()
- : 0;
- const int vertical_offset = kDialogVerticalMargin - offset_for_frame_insets;
- gfx::Size dialog_size = widget_->GetContentsView()->GetPreferredSize();
- widget_->SetBounds(
- gfx::Rect(gfx::Point(anchor_point_in_screen.x() - dialog_size.width() / 2,
- anchor_point_in_screen.y() + vertical_offset),
- dialog_size));
- }
- float SearchResultPageAnchoredDialog::AdjustVerticalTransformOffset(
- float default_offset) {
- // In addition to the host view (in host view coordinates), the
- // widget has to consider the parent (app list view) widget transform to
- // correctly follow the anchor view animation.
- const float parent_offset =
- host_view_->GetWidget()->GetLayer()->transform().To2dTranslation().y();
- return default_offset + parent_offset;
- }
- void SearchResultPageAnchoredDialog::OnWidgetDestroying(views::Widget* widget) {
- widget_ = nullptr;
- widget_observations_.RemoveAllObservations();
- if (callback_)
- std::move(callback_).Run();
- }
- void SearchResultPageAnchoredDialog::OnWidgetBoundsChanged(
- views::Widget* widget,
- const gfx::Rect& new_bounds) {
- // Reposition the dialog widget if the host widget bounds change (if the
- // bounds size remained the same, the host widget bounds change may not cause
- // app list layout, and thus the anchor bounds in the host view coordinates
- // may not change).
- if (widget == host_view_->GetWidget())
- UpdateBounds();
- }
- void SearchResultPageAnchoredDialog::OnViewBoundsChanged(
- views::View* observed_view) {
- UpdateBounds();
- }
- void SearchResultPageAnchoredDialog::OnViewPreferredSizeChanged(
- views::View* observed_view) {
- UpdateBounds();
- }
- } // namespace ash
|