blob: bb7d29a8e087ef11a58d665210cb30d978888c06 [file] [log] [blame]
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CC_INPUT_BROWSER_CONTROLS_OFFSET_MANAGER_H_
#define CC_INPUT_BROWSER_CONTROLS_OFFSET_MANAGER_H_
#include <memory>
#include "base/time/time.h"
#include "cc/input/browser_controls_state.h"
#include "cc/layers/layer_impl.h"
#include "cc/trees/browser_controls_params.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/geometry/vector2d_f.h"
namespace cc {
class BrowserControlsOffsetManagerClient;
// Manages the position of the browser controls.
class CC_EXPORT BrowserControlsOffsetManager {
public:
enum class AnimationDirection {
NO_ANIMATION,
SHOWING_CONTROLS,
HIDING_CONTROLS
};
static std::unique_ptr<BrowserControlsOffsetManager> Create(
BrowserControlsOffsetManagerClient* client,
float controls_show_threshold,
float controls_hide_threshold);
BrowserControlsOffsetManager(const BrowserControlsOffsetManager&) = delete;
virtual ~BrowserControlsOffsetManager();
BrowserControlsOffsetManager& operator=(const BrowserControlsOffsetManager&) =
delete;
// The offset from the window top to the top edge of the controls. Runs from 0
// (controls fully shown) to negative values (down is positive).
float ControlsTopOffset() const;
// The amount of offset of the web content area. Same as the current shown
// height of the browser controls.
float ContentTopOffset() const;
float TopControlsShownRatio() const;
float TopControlsHeight() const;
float TopControlsMinHeight() const;
// The minimum shown ratio top controls can have.
float TopControlsMinShownRatio() const;
// The current top controls min-height. If the min-height is changing with an
// animation, this will return a value between the old min-height and the new
// min-height, which is equal to the current visible min-height. Otherwise,
// this will return the same value as |TopControlsMinHeight()|.
float TopControlsMinHeightOffset() const;
// The amount of offset of the web content area, calculating from the bottom.
// Same as the current shown height of the bottom controls.
float ContentBottomOffset() const;
// Similar to TopControlsHeight(), this method should return a static value.
// The current animated height should be acquired from ContentBottomOffset().
float BottomControlsHeight() const;
float BottomControlsMinHeight() const;
float BottomControlsShownRatio() const;
// The minimum shown ratio bottom controls can have.
float BottomControlsMinShownRatio() const;
// The current bottom controls min-height. If the min-height is changing with
// an animation, this will return a value between the old min-height and the
// new min-height, which is equal to the current visible min-height.
// Otherwise, this will return the same value as |BottomControlsMinHeight()|.
float BottomControlsMinHeightOffset() const;
// Valid shown ratio range for the top controls. The values will be (0, 1) if
// there is no animation running.
std::pair<float, float> TopControlsShownRatioRange();
// Valid shown ratio range for the bottom controls. The values will be (0, 1)
// if there is no animation running.
std::pair<float, float> BottomControlsShownRatioRange();
bool HasAnimation();
void UpdateBrowserControlsState(BrowserControlsState constraints,
BrowserControlsState current,
bool animate);
BrowserControlsState PullConstraintForMainThread(
bool* out_changed_since_commit);
void OnBrowserControlsParamsChanged(bool animate_changes);
void ScrollBegin();
gfx::Vector2dF ScrollBy(const gfx::Vector2dF& pending_delta);
void ScrollEnd();
// The caller should ensure that |Pinch{Begin,End}| are called within
// the scope of |Scroll{Begin,End}|.
void PinchBegin();
void PinchEnd();
gfx::Vector2dF Animate(base::TimeTicks monotonic_time);
protected:
BrowserControlsOffsetManager(BrowserControlsOffsetManagerClient* client,
float controls_show_threshold,
float controls_hide_threshold);
private:
class Animation;
void ResetAnimations();
void SetupAnimation(AnimationDirection direction);
void StartAnimationIfNecessary();
void ResetBaseline();
float OldTopControlsMinShownRatio();
float OldBottomControlsMinShownRatio();
void UpdateOldBrowserControlsParams();
void InitAnimationForHeightChange(Animation* animation,
float start_ratio,
float stop_ratio);
// The client manages the lifecycle of this.
BrowserControlsOffsetManagerClient* client_;
BrowserControlsState permitted_state_;
// Accumulated scroll delta since last baseline reset
float accumulated_scroll_delta_;
// Content offset when last baseline reset occurred.
float baseline_top_content_offset_;
float baseline_bottom_content_offset_;
// The percent height of the visible control such that it must be shown
// when the user stops the scroll.
float controls_show_threshold_;
// The percent height of the visible control such that it must be hidden
// when the user stops the scroll.
float controls_hide_threshold_;
bool pinch_gesture_active_;
// Used to track whether the constraint has changed and we need up reflect
// the changes to Blink.
bool constraint_changed_since_commit_;
// The old browser controls params that are used to figure out how to animate
// the height and min-height changes.
BrowserControlsParams old_browser_controls_params_;
// Whether a min-height change animation is in progress.
bool top_min_height_change_in_progress_;
bool bottom_min_height_change_in_progress_;
// Current top/bottom controls min-height.
float top_controls_min_height_offset_;
float bottom_controls_min_height_offset_;
// Class that holds and manages the state of the controls animations.
class Animation {
public:
Animation();
// Whether the animation is initialized with a direction and start and stop
// values.
bool IsInitialized() { return initialized_; }
AnimationDirection Direction() { return direction_; }
void Initialize(AnimationDirection direction,
float start_value,
float stop_value,
int64_t duration,
bool jump_to_end_on_reset);
// Returns the animated value for the given monotonic time tick if the
// animation is initialized. Otherwise, returns |base::nullopt|.
base::Optional<float> Tick(base::TimeTicks monotonic_time);
// Set the minimum and maximum values the animation can have.
void SetBounds(float min, float max);
// Reset the properties. If |skip_to_end_on_reset_| is false, this function
// will return |base::nullopt|. Otherwise, it will return the end value
// (clamped to min-max).
base::Optional<float> Reset();
// Return the bounds.
float min_value() { return min_value_; }
float max_value() { return max_value_; }
private:
bool IsComplete(float value);
// Whether the animation is running.
bool started_ = false;
// Whether the animation is initialized by setting start and stop time and
// values.
bool initialized_ = false;
AnimationDirection direction_ = AnimationDirection::NO_ANIMATION;
// Monotonic start and stop times.
base::TimeTicks start_time_;
base::TimeTicks stop_time_;
// Animation duration.
base::TimeDelta duration_;
// Start and stop values.
float start_value_ = 0.f;
float stop_value_ = 0.f;
// Minimum and maximum values the animation can have, used to decide if the
// animation is complete.
float min_value_ = 0.f;
float max_value_ = 1.f;
// Whether to fast-forward to end when reset. It is still BCOM's
// responsibility to actually set the shown ratios using the value returned
// by ::Reset().
bool jump_to_end_on_reset_ = false;
};
Animation top_controls_animation_;
Animation bottom_controls_animation_;
};
} // namespace cc
#endif // CC_INPUT_BROWSER_CONTROLS_OFFSET_MANAGER_H_