Commit 7c56f7ee authored by Andrew Xu's avatar Andrew Xu Committed by Commit Bot

[Shelf] Calculate hotseat state transition with scoped class

Creating hotseat bounds animation which is triggered by hotseat state
change requires the hotseat state transition type. However, the current
method to calculate the transition type in HotseatWidget::SetState is
hard to reset the stored transition type after the transition completes.
In this CL, a scoped class is introduced to set/reset the transition
type stored in HotseatWidget. Note that the only place to set the
hotseat state then update the hotseat bounds is
ShelfLayoutManager::SetState(). It ensures the correctness of this CL.

Bug: 1024911
Change-Id: Ie68d182dbf105c4376898e7c0269a620194e6e6c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2235980Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Commit-Queue: Andrew Xu <andrewxu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#776238}
parent a71864a7
...@@ -52,6 +52,39 @@ void DoScopedAnimationSetting( ...@@ -52,6 +52,39 @@ void DoScopedAnimationSetting(
} }
} }
// Calculates the state transition type for the given previous state and
// the target state.
HotseatWidget::StateTransition CalculateHotseatStateTransition(
HotseatState previous_state,
HotseatState target_state) {
if (previous_state == HotseatState::kNone ||
target_state == HotseatState::kNone) {
return HotseatWidget::StateTransition::kOther;
}
if (previous_state == target_state)
return HotseatWidget::StateTransition::kOther;
const bool related_to_homelauncher =
(previous_state == HotseatState::kShownHomeLauncher ||
target_state == HotseatState::kShownHomeLauncher);
const bool related_to_extended = (previous_state == HotseatState::kExtended ||
target_state == HotseatState::kExtended);
const bool related_to_hidden = (previous_state == HotseatState::kHidden ||
target_state == HotseatState::kHidden);
if (related_to_homelauncher && related_to_extended)
return HotseatWidget::StateTransition::kHomeLauncherAndExtended;
if (related_to_homelauncher && related_to_hidden)
return HotseatWidget::StateTransition::kHomeLauncherAndHidden;
if (related_to_extended && related_to_hidden)
return HotseatWidget::StateTransition::kHiddenAndExtended;
return HotseatWidget::StateTransition::kOther;
}
// Custom window targeter for the hotseat. Used so the hotseat only processes // Custom window targeter for the hotseat. Used so the hotseat only processes
// events that land on the visible portion of the hotseat, and only while the // events that land on the visible portion of the hotseat, and only while the
// hotseat is not animating. // hotseat is not animating.
...@@ -325,6 +358,25 @@ void HotseatWidget::DelegateView::SetParentLayer(ui::Layer* layer) { ...@@ -325,6 +358,25 @@ void HotseatWidget::DelegateView::SetParentLayer(ui::Layer* layer) {
ReorderLayers(); ReorderLayers();
} }
////////////////////////////////////////////////////////////////////////////////
// ScopedInStateTransition
HotseatWidget::ScopedInStateTransition::ScopedInStateTransition(
HotseatWidget* hotseat_widget,
HotseatState old_state,
HotseatState target_state)
: hotseat_widget_(hotseat_widget) {
hotseat_widget_->state_transition_in_progress_ =
CalculateHotseatStateTransition(old_state, target_state);
}
HotseatWidget::ScopedInStateTransition::~ScopedInStateTransition() {
hotseat_widget_->state_transition_in_progress_.reset();
}
////////////////////////////////////////////////////////////////////////////////
// HotseatWidget
HotseatWidget::HotseatWidget() : delegate_view_(new DelegateView()) { HotseatWidget::HotseatWidget() : delegate_view_(new DelegateView()) {
ShelfConfig::Get()->AddObserver(this); ShelfConfig::Get()->AddObserver(this);
} }
...@@ -643,7 +695,6 @@ void HotseatWidget::SetState(HotseatState state) { ...@@ -643,7 +695,6 @@ void HotseatWidget::SetState(HotseatState state) {
if (state_ == state) if (state_ == state)
return; return;
old_state_ = state_;
state_ = state; state_ = state;
// If the hotseat is not extended we can use the normal targeting as the // If the hotseat is not extended we can use the normal targeting as the
...@@ -734,32 +785,4 @@ void HotseatWidget::LayoutHotseatByAnimation(double target_opacity, ...@@ -734,32 +785,4 @@ void HotseatWidget::LayoutHotseatByAnimation(double target_opacity,
SetBounds(target_bounds); SetBounds(target_bounds);
} }
HotseatWidget::StateTransition HotseatWidget::CalculateHotseatStateTransition()
const {
if (old_state_ == HotseatState::kNone || state_ == HotseatState::kNone)
return StateTransition::kOther;
if (old_state_ == state_)
return StateTransition::kOther;
const bool related_to_homelauncher =
(old_state_ == HotseatState::kShownHomeLauncher ||
state_ == HotseatState::kShownHomeLauncher);
const bool related_to_extended = (old_state_ == HotseatState::kExtended ||
state_ == HotseatState::kExtended);
const bool related_to_hidden =
(old_state_ == HotseatState::kHidden || state_ == HotseatState::kHidden);
if (related_to_homelauncher && related_to_extended)
return StateTransition::kHomeLauncherAndExtended;
if (related_to_homelauncher && related_to_hidden)
return StateTransition::kHomeLauncherAndHidden;
if (related_to_extended && related_to_hidden)
return StateTransition::kHiddenAndExtended;
return StateTransition::kOther;
}
} // namespace ash } // namespace ash
...@@ -29,6 +29,39 @@ class ASH_EXPORT HotseatWidget : public ShelfComponent, ...@@ -29,6 +29,39 @@ class ASH_EXPORT HotseatWidget : public ShelfComponent,
public ShelfConfig::Observer, public ShelfConfig::Observer,
public views::Widget { public views::Widget {
public: public:
// Defines the hotseat transition types.
enum class StateTransition {
// Hotseat state transits between kShownHomeLauncher and kExtended.
kHomeLauncherAndExtended,
// Hotseat state transits between kShownHomeLauncher and kHidden.
kHomeLauncherAndHidden,
// Hotseat state transits between kHidden and kExtended.
kHiddenAndExtended,
kOther
};
// Scoped class to notify HotseatWidget of hotseat state transition in
// progress. We should not calculate the state transition simply in
// HotseatWidget::SetState(). Otherwise it is hard to reset when the
// transition completes.
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:
HotseatWidget* hotseat_widget_ = nullptr;
};
HotseatWidget(); HotseatWidget();
~HotseatWidget() override; ~HotseatWidget() override;
...@@ -138,20 +171,6 @@ class ASH_EXPORT HotseatWidget : public ShelfComponent, ...@@ -138,20 +171,6 @@ class ASH_EXPORT HotseatWidget : public ShelfComponent,
private: private:
class DelegateView; class DelegateView;
// Defines the hotseat transition types.
enum class StateTransition {
// Hotseat state transits between kShownHomeLauncher and kExtended.
kHomeLauncherAndExtended,
// Hotseat state transits between kShownHomeLauncher and kHidden.
kHomeLauncherAndHidden,
// Hotseat state transits between kHidden and kExtended.
kHiddenAndExtended,
kOther
};
struct LayoutInputs { struct LayoutInputs {
gfx::Rect bounds; gfx::Rect bounds;
float shelf_view_opacity = 0.0f; float shelf_view_opacity = 0.0f;
...@@ -180,9 +199,6 @@ class ASH_EXPORT HotseatWidget : public ShelfComponent, ...@@ -180,9 +199,6 @@ class ASH_EXPORT HotseatWidget : public ShelfComponent,
void LayoutHotseatByAnimation(double target_opacity, void LayoutHotseatByAnimation(double target_opacity,
const gfx::Rect& target_bounds); const gfx::Rect& target_bounds);
// Calculates the state transition type before animating the hotseat.
StateTransition CalculateHotseatStateTransition() const;
// The set of inputs that impact this widget's layout. The assumption is that // The set of inputs that impact this widget's layout. The assumption is that
// this widget needs a relayout if, and only if, one or more of these has // this widget needs a relayout if, and only if, one or more of these has
// changed. // changed.
...@@ -190,9 +206,11 @@ class ASH_EXPORT HotseatWidget : public ShelfComponent, ...@@ -190,9 +206,11 @@ class ASH_EXPORT HotseatWidget : public ShelfComponent,
gfx::Rect target_bounds_; gfx::Rect target_bounds_;
HotseatState old_state_ = HotseatState::kNone;
HotseatState state_ = HotseatState::kNone; HotseatState state_ = HotseatState::kNone;
// Indicates the type of the hotseat state transition in progress.
base::Optional<StateTransition> state_transition_in_progress_;
Shelf* shelf_ = nullptr; Shelf* shelf_ = nullptr;
// View containing the shelf items within an active user session. Owned by // View containing the shelf items within an active user session. Owned by
......
...@@ -1295,7 +1295,15 @@ void ShelfLayoutManager::SetState(ShelfVisibilityState visibility_state) { ...@@ -1295,7 +1295,15 @@ void ShelfLayoutManager::SetState(ShelfVisibilityState visibility_state) {
MaybeUpdateShelfBackground(change_type); MaybeUpdateShelfBackground(change_type);
CalculateTargetBoundsAndUpdateWorkArea(); CalculateTargetBoundsAndUpdateWorkArea();
shelf_->hotseat_widget()->SetState(new_hotseat_state); HotseatWidget* hotseat_widget = shelf_->hotseat_widget();
hotseat_widget->SetState(new_hotseat_state);
// Called before UpdateBoundsAndOpacity(). Because creation of the hotseat
// bounds animation which is triggered by hotseat state update requires the
// state transition type.
HotseatWidget::ScopedInStateTransition scoped_in_state_transition(
hotseat_widget, previous_hotseat_state, new_hotseat_state);
UpdateBoundsAndOpacity(true /* animate */); UpdateBoundsAndOpacity(true /* animate */);
// OnAutoHideStateChanged Should be emitted when: // OnAutoHideStateChanged Should be emitted when:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment