| // Copyright 2021 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef ASH_APP_LIST_APP_LIST_BUBBLE_PRESENTER_H_ |
| #define ASH_APP_LIST_APP_LIST_BUBBLE_PRESENTER_H_ |
| |
| #include <stdint.h> |
| |
| #include <memory> |
| |
| #include "ash/ash_export.h" |
| #include "ash/public/cpp/app_list/app_list_types.h" |
| #include "ash/public/cpp/shelf_types.h" |
| #include "ash/shelf/shelf.h" |
| #include "ash/shelf/shelf_observer.h" |
| #include "base/memory/weak_ptr.h" |
| #include "base/scoped_observation.h" |
| #include "third_party/abseil-cpp/absl/types/optional.h" |
| #include "ui/display/display_observer.h" |
| #include "ui/views/widget/widget_observer.h" |
| #include "ui/wm/public/activation_change_observer.h" |
| |
| namespace aura { |
| class Window; |
| } // namespace aura |
| |
| namespace ash { |
| |
| class AppListBubbleEventFilter; |
| class AppListBubbleView; |
| class AppListControllerImpl; |
| enum class AppListSortOrder; |
| |
| // Manages the UI for the bubble launcher used in clamshell mode. Handles |
| // showing and hiding the UI, as well as bounds computations. Only one bubble |
| // can be visible at a time, across all displays. |
| class ASH_EXPORT AppListBubblePresenter : public views::WidgetObserver, |
| public wm::ActivationChangeObserver, |
| public display::DisplayObserver, |
| public ShelfObserver { |
| public: |
| explicit AppListBubblePresenter(AppListControllerImpl* controller); |
| AppListBubblePresenter(const AppListBubblePresenter&) = delete; |
| AppListBubblePresenter& operator=(const AppListBubblePresenter&) = delete; |
| ~AppListBubblePresenter() override; |
| |
| // Closes the bubble if it is open and prepares for shutdown. |
| void Shutdown(); |
| |
| // Shows the bubble on the display with `display_id`. The bubble is shown |
| // asynchronously (after a delay) because the continue suggestions need to be |
| // refreshed before the bubble views can be created and animated. This delay |
| // is skipped in unit tests (see TestAppListClient) for convenience. Larger |
| // tests (e.g. browser_tests) may need to wait for the window to open. |
| void Show(int64_t display_id); |
| |
| // Shows or hides the bubble on the display with `display_id`. Returns the |
| // appropriate ShelfAction to indicate whether the bubble was shown or hidden. |
| ShelfAction Toggle(int64_t display_id); |
| |
| // Closes and destroys the bubble. |
| void Dismiss(); |
| |
| // Returns the bubble window or nullptr if it is not open. |
| aura::Window* GetWindow() const; |
| |
| // Returns true if the bubble is showing on any display. |
| bool IsShowing() const; |
| |
| // Returns true if the assistant page is showing. |
| bool IsShowingEmbeddedAssistantUI() const; |
| |
| // Switches to the assistant page. Requires the bubble to be open. |
| void ShowEmbeddedAssistantUI(); |
| |
| // Updates the continue section visibility based on user preference. |
| void UpdateContinueSectionVisibility(); |
| |
| // Handles `AppListController::UpdateAppListWithNewSortingOrder()` for the |
| // bubble launcher. |
| void UpdateForNewSortingOrder( |
| const absl::optional<AppListSortOrder>& new_order, |
| bool animate, |
| base::OnceClosure update_position_closure); |
| |
| // views::WidgetObserver: |
| void OnWidgetDestroying(views::Widget* widget) override; |
| |
| // wm::ActivationChangeObserver: |
| void OnWindowActivating(ActivationReason reason, |
| aura::Window* gaining_active, |
| aura::Window* losing_active) override {} |
| void OnWindowActivated(ActivationReason reason, |
| aura::Window* gained_active, |
| aura::Window* lost_active) override; |
| |
| // DisplayObserver: |
| void OnDisplayMetricsChanged(const display::Display& display, |
| uint32_t changed_metrics) override; |
| |
| // ShelfObserver: |
| void OnShelfShuttingDown() override; |
| |
| // Returns the preferred width for the bubble launcher for the |root_window|. |
| int GetPreferredBubbleWidth(aura::Window* root_window) const; |
| |
| views::Widget* bubble_widget_for_test() { return bubble_widget_; } |
| AppListBubbleView* bubble_view_for_test() { return bubble_view_; } |
| |
| private: |
| // Callback for zero state search update. Builds the bubble widget and views |
| // on display `display_id` and triggers the show animation. |
| void OnZeroStateSearchDone(int64_t display_id); |
| |
| // Callback for AppListBubbleEventFilter, used to notify this of presses |
| // outside the bubble. |
| void OnPressOutsideBubble(); |
| |
| // Gets the display id for the display `bubble_widget_` is shown on. Returns |
| // kInvalidDisplayId if not shown. |
| int64_t GetDisplayId() const; |
| |
| // Callback for the hide animation. |
| void OnHideAnimationEnded(); |
| |
| AppListControllerImpl* const controller_; |
| |
| // Whether the view is showing or animating to show. Note that the |
| // `bubble_widget_` may be null during the zero state search called in |
| // `Show()`. |
| bool is_target_visibility_show_ = false; |
| |
| // Owned by native widget. |
| views::Widget* bubble_widget_ = nullptr; |
| |
| // Owned by views. |
| AppListBubbleView* bubble_view_ = nullptr; |
| |
| // The page to show after the views are constructed. |
| AppListBubblePage target_page_ = AppListBubblePage::kApps; |
| |
| // Closes the widget when the user clicks outside of it. |
| std::unique_ptr<AppListBubbleEventFilter> bubble_event_filter_; |
| |
| // Observes display configuration changes. |
| display::ScopedDisplayObserver display_observer_{this}; |
| |
| base::ScopedObservation<Shelf, ShelfObserver> shelf_observer_{this}; |
| |
| base::WeakPtrFactory<AppListBubblePresenter> weak_factory_{this}; |
| }; |
| |
| } // namespace ash |
| |
| #endif // ASH_APP_LIST_APP_LIST_BUBBLE_PRESENTER_H_ |