1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292
|
// Copyright 2016 The Chromium Authors
// 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 <optional>
#include <utility>
#include "base/memory/raw_ptr.h"
#include "base/time/time.h"
#include "base/types/optional_ref.h"
#include "cc/input/browser_controls_offset_tag_modifications.h"
#include "cc/input/browser_controls_state.h"
#include "cc/layers/layer_impl.h"
#include "cc/trees/browser_controls_params.h"
#include "components/viz/common/quads/offset_tag.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 {
kNoAnimation,
kShowingControls,
kHidingControls
};
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;
int TopControlsAdditionalHeight() 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;
viz::OffsetTag ContentOffsetTag() const;
viz::OffsetTag TopControlsOffsetTag() 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;
int BottomControlsAdditionalHeight() 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;
viz::OffsetTag BottomControlsOffsetTag() const;
bool HasOffsetTag() 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();
bool IsAnimatingToShowControls() const {
return top_controls_animation_.IsInitialized() &&
top_controls_animation_.Direction() ==
AnimationDirection::kShowingControls;
}
// See UpdateBrowserControlsState in
// third_party/blink/public/mojom/frame/frame.mojom
void UpdateBrowserControlsState(
BrowserControlsState constraints,
BrowserControlsState current,
bool animate,
base::optional_ref<const BrowserControlsOffsetTagModifications>
offset_tag_modifications);
// Return the browser control constraint that must be synced to the
// main renderer thread (to trigger viewport and related changes).
BrowserControlsState PullConstraintForMainThread(
bool* out_changed_since_commit);
// Called to notify this object that the control constraint has
// been pushed to the main thread. When a compositor commit does not
// happen the value pulled by the method above may not be synced;
// a call to this method notifies us that it has.
void NotifyConstraintSyncedToMainThread();
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);
// Predict what the outer viewport container bounds delta will be as browser
// controls are shown or hidden during a scroll gesture before the Blink
// WebView is resized to reflect the new state.
double PredictViewportBoundsDelta(double current_bounds_delta,
gfx::Vector2dF scroll_distance);
void ResetAnimations();
protected:
BrowserControlsOffsetManager(BrowserControlsOffsetManagerClient* client,
float controls_show_threshold,
float controls_hide_threshold);
private:
class Animation;
void SetupAnimation(AnimationDirection direction);
void StartAnimationIfNecessary();
void ResetBaseline();
float OldTopControlsMinShownRatio();
float OldBottomControlsMinShownRatio();
void UpdateOldBrowserControlsParams();
void InitAnimationForHeightChange(Animation* animation,
float start_ratio,
float stop_ratio);
void SetTopMinHeightOffsetAnimationRange(float from, float to);
void SetBottomMinHeightOffsetAnimationRange(float from, float to);
// The client manages the lifecycle of this.
raw_ptr<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_;
// Minimum and maximum values |top_controls_min_height_offset_| can take
// during the current min-height change animation.
std::optional<std::pair<float, float>> top_min_height_offset_animation_range_;
// Minimum and maximum values |bottom_controls_min_height_offset_| can take
// during the current min-height change animation.
std::optional<std::pair<float, float>>
bottom_min_height_offset_animation_range_;
// Should ScrollEnd() animate the controls into view? This is used if there's
// a race between chrome starting an animation to show the controls while the
// user is doing a scroll gesture, which would cancel animations. We want to
// err on the side of showing the controls, so that the user realizes that
// they're an option. If we have started, but not yet completed an animation
// to show the controls when the scroll starts, or if one starts during the
// gesture, then we reorder the animation until after the scroll.
bool show_controls_when_scroll_completes_ = false;
BrowserControlsOffsetTagModifications offset_tag_modifications_;
// 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() const { return initialized_; }
AnimationDirection Direction() const { 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 |std::nullopt|.
std::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 |std::nullopt|. Otherwise, it will return the end value
// (clamped to min-max).
std::optional<float> Reset();
// Returns the value the animation will end on. This will be the stop_value
// passed to the constructor clamped by the currently configured bounds.
float FinalValue();
// 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::kNoAnimation;
// 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_
|