#ifndef ASH_SYSTEM_HOLDING_SPACE_HOLDING_SPACE_TRAY_H_
#define ASH_SYSTEM_HOLDING_SPACE_HOLDING_SPACE_TRAY_H_
#include <memory>
#include <vector>
#include "ash/ash_export.h"
#include "ash/drag_drop/scoped_drag_drop_observer.h"
#include "ash/public/cpp/holding_space/holding_space_controller.h"
#include "ash/public/cpp/holding_space/holding_space_controller_observer.h"
#include "ash/public/cpp/holding_space/holding_space_model.h"
#include "ash/public/cpp/holding_space/holding_space_model_observer.h"
#include "ash/public/cpp/session/session_controller.h"
#include "ash/public/cpp/session/session_observer.h"
#include "ash/style/ash_color_provider.h"
#include "ash/system/holding_space/holding_space_tray_bubble.h"
#include "ash/system/tray/tray_background_view.h"
#include "base/callback_list.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/scoped_observation.h"
#include "base/timer/timer.h"
#include "ui/base/metadata/metadata_header_macros.h"
#include "ui/compositor/layer_tree_owner.h"
#include "ui/menus/simple_menu_model.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_observer.h"
class PrefChangeRegistrar;
namespace aura {
namespace client {
class DragDropClientObserver;
}
}
namespace views {
class ImageView;
}
namespace ash {
class HoldingSpaceTrayIcon;
class ProgressIndicator;
class ASH_EXPORT HoldingSpaceTray : public TrayBackgroundView,
public HoldingSpaceControllerObserver,
public HoldingSpaceModelObserver,
public SessionObserver,
public ui::SimpleMenuModel::Delegate,
public views::WidgetObserver {
METADATA_HEADER(HoldingSpaceTray, TrayBackgroundView)
public:
explicit HoldingSpaceTray(Shelf* shelf);
HoldingSpaceTray(const HoldingSpaceTray& other) = delete;
HoldingSpaceTray& operator=(const HoldingSpaceTray& other) = delete;
~HoldingSpaceTray() override;
void Initialize() override;
void ClickedOutsideBubble(const ui::LocatedEvent& event) override;
views::View* GetTooltipHandlerForPoint(const gfx::Point& point) override;
void HandleLocaleChange() override;
void HideBubbleWithView(const TrayBubbleView* bubble_view) override;
void AnchorUpdated() override;
void UpdateAfterLoginStatusChange() override;
void CloseBubbleInternal() override;
void ShowBubble() override;
TrayBubbleView* GetBubbleView() override;
views::Widget* GetBubbleWidget() const override;
void SetVisiblePreferred(bool visible_preferred) override;
bool GetDropFormats(int* formats,
std::set<ui::ClipboardFormatType>* format_types) override;
bool AreDropTypesRequired() override;
bool CanDrop(const ui::OSExchangeData& data) override;
int OnDragUpdated(const ui::DropTargetEvent& event) override;
views::View::DropCallback GetDropCallback(
const ui::DropTargetEvent& event) override;
void Layout(PassKey) override;
void VisibilityChanged(views::View* starting_from, bool is_visible) override;
void OnThemeChanged() override;
void OnShouldShowAnimationChanged(bool should_animate) override;
std::unique_ptr<ui::SimpleMenuModel> CreateContextMenuModel() override;
void UpdateTrayItemColor(bool is_active) override;
void UpdateVisibility();
HoldingSpaceTrayBubble* bubble_for_testing() { return bubble_.get(); }
void FirePreviewsUpdateTimerIfRunningForTesting();
void set_use_zero_previews_update_delay_for_testing(bool zero_delay) {
use_zero_previews_update_delay_ = zero_delay;
}
private:
std::u16string GetAccessibleNameForBubble() override;
bool ShouldEnableExtraKeyboardAccessibility() override;
void HideBubble(const TrayBubbleView* bubble_view) override;
void OnHoldingSpaceModelAttached(HoldingSpaceModel* model) override;
void OnHoldingSpaceModelDetached(HoldingSpaceModel* model) override;
void OnHoldingSpaceItemsAdded(
const std::vector<const HoldingSpaceItem*>& items) override;
void OnHoldingSpaceItemsRemoved(
const std::vector<const HoldingSpaceItem*>& items) override;
void OnHoldingSpaceItemInitialized(const HoldingSpaceItem* item) override;
void OnActiveUserPrefServiceChanged(PrefService* prefs) override;
void OnSessionStateChanged(session_manager::SessionState state) override;
void ExecuteCommand(int command_id, int event_flags) override;
void OnWidgetDragWillStart(views::Widget* widget) override;
void ObservePrefService(PrefService* prefs);
void OnTrayButtonPressed(const ui::Event& event);
void UpdatePreviewsState();
void UpdatePreviewsVisibility();
void SchedulePreviewsIconUpdate();
void UpdatePreviewsIcon();
bool PreviewsShown() const;
void UpdateDefaultTrayIcon();
void UpdateDropTargetState(ScopedDragDropObserver::EventType event_type,
const ui::DropTargetEvent* event);
void SetShouldAnimate(bool should_animate);
void PerformDrop(const ui::DropTargetEvent& event,
ui::mojom::DragOperation& output_drag_op,
std::unique_ptr<ui::LayerTreeOwner> drag_image_layer_owner);
std::unique_ptr<HoldingSpaceTrayBubble> bubble_;
std::unique_ptr<aura::client::DragDropClientObserver> drag_drop_observer_;
raw_ptr<views::ImageView> default_tray_icon_ = nullptr;
raw_ptr<HoldingSpaceTrayIcon> previews_tray_icon_ = nullptr;
raw_ptr<views::View> drop_target_overlay_ = nullptr;
raw_ptr<views::ImageView> drop_target_icon_ = nullptr;
std::unique_ptr<ProgressIndicator> progress_indicator_;
base::CallbackListSubscription
progress_indicator_progress_changed_callback_list_subscription_;
std::unique_ptr<PrefChangeRegistrar> pref_change_registrar_;
base::OneShotTimer previews_update_;
bool use_zero_previews_update_delay_ = false;
std::optional<bool> can_drop_to_pin_;
bool did_drop_to_pin_ = false;
base::ScopedObservation<HoldingSpaceController,
HoldingSpaceControllerObserver>
controller_observer_{this};
base::ScopedObservation<HoldingSpaceModel, HoldingSpaceModelObserver>
model_observer_{this};
base::ScopedObservation<SessionController, SessionObserver> session_observer_{
this};
base::ScopedObservation<views::Widget, views::WidgetObserver>
widget_observer_{this};
std::unique_ptr<base::ScopedClosureRunner> animation_disabler_;
base::WeakPtrFactory<HoldingSpaceTray> weak_factory_{this};
};
}
#endif