#ifndef ASH_SHELF_SHELF_H_
#define ASH_SHELF_SHELF_H_
#include <memory>
#include "ash/ash_export.h"
#include "ash/public/cpp/metrics_util.h"
#include "ash/public/cpp/shelf_types.h"
#include "ash/shelf/desk_button_widget.h"
#include "ash/shelf/shelf_layout_manager_observer.h"
#include "ash/shelf/shelf_locking_manager.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
namespace aura {
class Window;
}
namespace gfx {
class Rect;
}
namespace ui {
class GestureEvent;
class MouseWheelEvent;
class MouseEvent;
class ScrollEvent;
}
namespace ash {
enum class AnimationChangeType;
class HotseatWidget;
class HotseatWidgetAnimationMetricsReporter;
class NavigationWidgetAnimationMetricsReporter;
class ShelfFocusCycler;
class LoginShelfWidget;
class ShelfLayoutManager;
class ShelfLayoutManagerTest;
class ShelfLockingManager;
class ShelfNavigationWidget;
class ShelfView;
class ShelfWidget;
class StatusAreaWidget;
class ShelfObserver;
class WorkAreaInsets;
class ShelfTooltipManager;
template <typename T>
T SelectValueByShelfAlignment(ShelfAlignment alignment,
T bottom,
T left,
T right) {
switch (alignment) {
case ShelfAlignment::kBottom:
case ShelfAlignment::kBottomLocked:
return bottom;
case ShelfAlignment::kLeft:
return left;
case ShelfAlignment::kRight:
return right;
}
NOTREACHED();
}
bool IsHorizontalAlignment(ShelfAlignment alignment);
template <typename T>
T PrimaryAxisValueByShelfAlignment(ShelfAlignment alignment,
T horizontal,
T vertical) {
return IsHorizontalAlignment(alignment) ? horizontal : vertical;
}
class ASH_EXPORT Shelf : public ShelfLayoutManagerObserver {
public:
class ScopedAutoHideLock {
public:
explicit ScopedAutoHideLock(Shelf* shelf) : shelf_(shelf) {
++shelf_->auto_hide_lock_;
}
ScopedAutoHideLock(const ScopedAutoHideLock&) = delete;
ScopedAutoHideLock& operator=(const ScopedAutoHideLock&) = delete;
~ScopedAutoHideLock() {
--shelf_->auto_hide_lock_;
DCHECK_GE(shelf_->auto_hide_lock_, 0);
}
private:
raw_ptr<Shelf> shelf_;
};
class ScopedDisableAutoHide {
public:
explicit ScopedDisableAutoHide(Shelf* shelf);
ScopedDisableAutoHide(const ScopedDisableAutoHide&) = delete;
ScopedDisableAutoHide& operator=(const ScopedDisableAutoHide&) = delete;
~ScopedDisableAutoHide();
Shelf* weak_shelf() { return shelf_.get(); }
private:
base::WeakPtr<Shelf> const shelf_;
};
Shelf();
Shelf(const Shelf&) = delete;
Shelf& operator=(const Shelf&) = delete;
~Shelf() override;
static Shelf* ForWindow(aura::Window* window);
static void LaunchShelfItem(int item_index);
static void ActivateShelfItem(int item_index);
static void ActivateShelfItemOnDisplay(int item_index, int64_t display_id);
static void UpdateShelfVisibility();
void CreateNavigationWidget(aura::Window* container);
void CreateDeskButtonWidget(aura::Window* container);
void CreateHotseatWidget(aura::Window* container);
void CreateStatusAreaWidget(aura::Window* status_container);
void CreateShelfWidget(aura::Window* root);
void ShutdownShelfWidget();
void DestroyShelfWidget();
bool IsVisible() const;
const aura::Window* GetWindow() const;
aura::Window* GetWindow();
void SetAlignment(ShelfAlignment alignment);
bool IsHorizontalAlignment() const;
template <typename T>
T SelectValueForShelfAlignment(T bottom, T left, T right) const {
return SelectValueByShelfAlignment(alignment_, bottom, left, right);
}
template <typename T>
T PrimaryAxisValue(T horizontal, T vertical) const {
return IsHorizontalAlignment() ? horizontal : vertical;
}
void SetAutoHideBehavior(ShelfAutoHideBehavior behavior);
ShelfAutoHideState GetAutoHideState() const;
void UpdateAutoHideState();
ShelfBackgroundType GetBackgroundType() const;
void UpdateVisibilityState();
void MaybeUpdateShelfBackground();
ShelfVisibilityState GetVisibilityState() const;
gfx::Rect GetShelfBoundsInScreen() const;
gfx::Rect GetIdealBounds() const;
gfx::Rect GetIdealBoundsForWorkAreaCalculation();
gfx::Rect GetScreenBoundsOfItemIconForWindow(aura::Window* window);
bool ProcessGestureEvent(const ui::GestureEvent& event);
void ProcessMouseEvent(const ui::MouseEvent& event);
void ProcessScrollEvent(ui::ScrollEvent* event);
void ProcessMouseWheelEvent(ui::MouseWheelEvent* event);
void AddObserver(ShelfObserver* observer);
void RemoveObserver(ShelfObserver* observer);
void NotifyShelfIconPositionsChanged();
StatusAreaWidget* GetStatusAreaWidget() const;
gfx::Rect GetSystemTrayAnchorRect() const;
bool ShouldHideOnSecondaryDisplay(session_manager::SessionState state);
void SetVirtualKeyboardBoundsForTesting(const gfx::Rect& bounds);
ShelfLockingManager* GetShelfLockingManagerForTesting();
ShelfView* GetShelfViewForTesting();
ShelfLayoutManager* shelf_layout_manager() const {
return shelf_layout_manager_;
}
ShelfWidget* shelf_widget() const { return shelf_widget_.get(); }
ShelfNavigationWidget* navigation_widget() const {
return navigation_widget_.get();
}
DeskButtonWidget* desk_button_widget() const {
return desk_button_widget_.get();
}
HotseatWidget* hotseat_widget() const { return hotseat_widget_.get(); }
StatusAreaWidget* status_area_widget() const {
return status_area_widget_.get();
}
LoginShelfWidget* login_shelf_widget() { return login_shelf_widget_.get(); }
ShelfAlignment alignment() const { return alignment_; }
ShelfAutoHideBehavior auto_hide_behavior() const {
return auto_hide_behavior_;
}
ShelfAlignment in_session_alignment() const {
return shelf_locking_manager_.in_session_alignment();
}
ShelfAutoHideBehavior in_session_auto_hide_behavior() const {
return shelf_locking_manager_.in_session_auto_hide_behavior();
}
ShelfFocusCycler* shelf_focus_cycler() { return shelf_focus_cycler_.get(); }
int auto_hide_lock() const { return auto_hide_lock_; }
int disable_auto_hide() const { return disable_auto_hide_; }
ShelfTooltipManager* tooltip() { return tooltip_.get(); }
metrics_util::ReportCallback GetHotseatTransitionReportCallback(
HotseatState target_state);
metrics_util::ReportCallback GetTranslucentBackgroundReportCallback(
HotseatState target_state);
metrics_util::ReportCallback GetNavigationWidgetAnimationReportCallback(
HotseatState target_hotseat_state);
protected:
void WillDeleteShelfLayoutManager() override;
void OnShelfVisibilityStateChanged(ShelfVisibilityState new_state) override;
void OnAutoHideStateChanged(ShelfAutoHideState new_state) override;
void OnBackgroundUpdated(ShelfBackgroundType background_type,
AnimationChangeType change_type) override;
void OnHotseatStateChanged(HotseatState old_state,
HotseatState new_state) override;
void OnWorkAreaInsetsChanged() override;
private:
class AutoDimEventHandler;
class AutoHideEventHandler;
friend class DimShelfLayoutManagerTestBase;
friend class ShelfLayoutManagerTest;
void DimShelf();
void UndimShelf();
bool HasDimShelfTimer();
WorkAreaInsets* GetWorkAreaInsets() const;
base::WeakPtr<Shelf> GetWeakPtr();
raw_ptr<ShelfLayoutManager> shelf_layout_manager_ = nullptr;
std::unique_ptr<ShelfNavigationWidget> navigation_widget_;
std::unique_ptr<DeskButtonWidget> desk_button_widget_;
std::unique_ptr<HotseatWidget> hotseat_widget_;
std::unique_ptr<StatusAreaWidget> status_area_widget_;
std::unique_ptr<ShelfWidget> shelf_widget_;
std::unique_ptr<LoginShelfWidget> login_shelf_widget_;
ShelfAlignment alignment_ = ShelfAlignment::kBottomLocked;
ShelfAutoHideBehavior auto_hide_behavior_ =
ShelfAutoHideBehavior::kAlwaysHidden;
ShelfLockingManager shelf_locking_manager_;
base::ObserverList<ShelfObserver>::Unchecked observers_;
std::unique_ptr<AutoHideEventHandler> auto_hide_event_handler_;
std::unique_ptr<AutoDimEventHandler> auto_dim_event_handler_;
std::unique_ptr<ShelfFocusCycler> shelf_focus_cycler_;
std::unique_ptr<HotseatWidgetAnimationMetricsReporter>
hotseat_transition_metrics_reporter_;
std::unique_ptr<HotseatWidgetAnimationMetricsReporter>
translucent_background_metrics_reporter_;
std::unique_ptr<NavigationWidgetAnimationMetricsReporter>
navigation_widget_metrics_reporter_;
int auto_hide_lock_ = 0;
int disable_auto_hide_ = 0;
std::unique_ptr<ShelfTooltipManager> tooltip_;
base::WeakPtrFactory<Shelf> weak_ptr_factory_{this};
};
}
#endif