#ifndef ASH_SHELF_HOTSEAT_WIDGET_H_
#define ASH_SHELF_HOTSEAT_WIDGET_H_
#include <memory>
#include <optional>
#include "ash/ash_export.h"
#include "ash/public/cpp/metrics_util.h"
#include "ash/public/cpp/shelf_config.h"
#include "ash/public/cpp/shelf_types.h"
#include "ash/shelf/hotseat_transition_animator.h"
#include "ash/shelf/shelf_component.h"
#include "base/memory/raw_ptr.h"
#include "ui/views/widget/widget.h"
namespace aura {
class ScopedWindowTargeter;
}
namespace ash {
class ScrollableShelfView;
class Shelf;
class ShelfView;
class HotseatTransitionAnimator;
class HotseatWidgetDelegateView;
class ASH_EXPORT HotseatWidget : public ShelfComponent,
public ShelfConfig::Observer,
public views::Widget {
public:
enum class StateTransition {
kHomeLauncherAndExtended,
kHomeLauncherAndHidden,
kHiddenAndExtended,
kOther
};
class ScopedInStateTransition {
public:
ScopedInStateTransition(HotseatWidget* hotseat_widget,
HotseatState old_state,
HotseatState target_state);
~ScopedInStateTransition();
ScopedInStateTransition(const ScopedInStateTransition& rhs) = delete;
ScopedInStateTransition& operator=(const ScopedInStateTransition& rhs) =
delete;
private:
raw_ptr<HotseatWidget> hotseat_widget_ = nullptr;
};
HotseatWidget();
HotseatWidget(const HotseatWidget&) = delete;
HotseatWidget& operator=(const HotseatWidget&) = delete;
~HotseatWidget() override;
static bool ShouldShowHotseatBackground();
void Initialize(aura::Window* container, Shelf* shelf);
void OnHotseatTransitionAnimatorCreated(HotseatTransitionAnimator* animator);
void OnMouseEvent(ui::MouseEvent* event) override;
void OnGestureEvent(ui::GestureEvent* event) override;
bool OnNativeWidgetActivationChanged(bool active) override;
void OnShelfConfigUpdated() override;
bool IsExtended() const;
void FocusFirstOrLastFocusableChild(bool last);
void OnTabletModeChanged();
float CalculateShelfViewOpacity() const;
void UpdateTranslucentBackground();
void InitializeAccessibilityProperties();
int CalculateHotseatYInScreen(HotseatState hotseat_target_state) const;
gfx::Size CalculateTargetBoundsSize(HotseatState hotseat_target_state) const;
gfx::Size CalculateInlineAppBarSize() const;
void ReserveSpaceForAdjacentWidgets(const gfx::Insets& space);
void CalculateTargetBounds() override;
gfx::Rect GetTargetBounds() const override;
void UpdateLayout(bool animate) override;
void UpdateTargetBoundsForGesture(int shelf_position) override;
void set_target_bounds(gfx::Rect target_bounds) {
target_bounds_ = target_bounds;
}
gfx::Size GetTranslucentBackgroundSize() const;
bool IsShowingShelfMenu() const;
bool EventTargetsShelfView(const ui::LocatedEvent& event) const;
ShelfView* GetShelfView();
const ShelfView* GetShelfView() const;
int GetHotseatSize() const;
int GetHotseatFullDragAmount() const;
bool UpdateTargetHotseatDensityIfNeeded();
int GetHotseatBackgroundBlurForTest() const;
bool GetIsTranslucentBackgroundVisibleForTest() const;
metrics_util::ReportCallback GetTranslucentBackgroundReportCallback();
void SetState(HotseatState state);
HotseatState state() const { return state_; }
ScrollableShelfView* scrollable_shelf_view() {
return scrollable_shelf_view_;
}
const ScrollableShelfView* scrollable_shelf_view() const {
return scrollable_shelf_view_;
}
bool is_manually_extended() const { return is_manually_extended_; }
void set_manually_extended(bool value) { is_manually_extended_ = value; }
HotseatDensity target_hotseat_density() const {
return target_hotseat_density_;
}
ui::Layer* GetLayerForNudgeAnimation();
bool CalculateShelfOverflow(bool use_target_bounds) const;
private:
struct LayoutInputs {
gfx::Rect bounds;
float shelf_view_opacity = 0.0f;
bool is_active_session_state = false;
gfx::Insets reserved_space_;
bool operator==(const LayoutInputs& other) const {
return bounds == other.bounds &&
shelf_view_opacity == other.shelf_view_opacity &&
is_active_session_state == other.is_active_session_state &&
reserved_space_ == other.reserved_space_;
}
};
LayoutInputs GetLayoutInputs() const;
void MaybeAdjustTargetBoundsForAppScaling(HotseatState hotseat_target_state);
HotseatDensity CalculateTargetHotseatDensity() const;
void LayoutHotseatByAnimation(double target_opacity,
const gfx::Rect& target_bounds);
void StartHotseatTransitionAnimation(StateTransition state_transition,
double target_opacity,
const gfx::Rect& target_bounds);
void StartNormalBoundsAnimation(double target_opacity,
const gfx::Rect& target_bounds);
std::optional<LayoutInputs> layout_inputs_;
gfx::Rect target_bounds_;
gfx::Size target_size_for_shown_state_;
HotseatState state_ = HotseatState::kNone;
std::optional<StateTransition> state_transition_in_progress_;
raw_ptr<Shelf> shelf_ = nullptr;
raw_ptr<ScrollableShelfView, DanglingUntriaged> scrollable_shelf_view_ =
nullptr;
raw_ptr<HotseatWidgetDelegateView> delegate_view_ = nullptr;
bool is_manually_extended_ = false;
HotseatDensity target_hotseat_density_ = HotseatDensity::kNormal;
std::unique_ptr<aura::ScopedWindowTargeter> hotseat_window_targeter_;
gfx::Insets reserved_space_;
};
}
#endif