| OLD | NEW |
| (Empty) |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "core/frame/TopControls.h" | |
| 6 | |
| 7 #include "core/frame/FrameHost.h" | |
| 8 #include "core/frame/VisualViewport.h" | |
| 9 #include "core/page/ChromeClient.h" | |
| 10 #include "platform/geometry/FloatSize.h" | |
| 11 #include <algorithm> // for std::min and std::max | |
| 12 | |
| 13 namespace blink { | |
| 14 | |
| 15 TopControls::TopControls(const FrameHost& frameHost) | |
| 16 : m_frameHost(&frameHost), | |
| 17 m_height(0), | |
| 18 m_shownRatio(0), | |
| 19 m_baselineContentOffset(0), | |
| 20 m_accumulatedScrollDelta(0), | |
| 21 m_shrinkViewport(false), | |
| 22 m_permittedState(WebTopControlsBoth) {} | |
| 23 | |
| 24 DEFINE_TRACE(TopControls) { | |
| 25 visitor->trace(m_frameHost); | |
| 26 } | |
| 27 | |
| 28 void TopControls::scrollBegin() { | |
| 29 resetBaseline(); | |
| 30 } | |
| 31 | |
| 32 FloatSize TopControls::scrollBy(FloatSize pendingDelta) { | |
| 33 if ((m_permittedState == WebTopControlsShown && pendingDelta.height() > 0) || | |
| 34 (m_permittedState == WebTopControlsHidden && pendingDelta.height() < 0)) | |
| 35 return pendingDelta; | |
| 36 | |
| 37 if (m_height == 0) | |
| 38 return pendingDelta; | |
| 39 | |
| 40 float oldOffset = contentOffset(); | |
| 41 float pageScale = m_frameHost->visualViewport().scale(); | |
| 42 | |
| 43 // Update accumulated vertical scroll and apply it to top controls | |
| 44 // Compute scroll delta in viewport space by applying page scale | |
| 45 m_accumulatedScrollDelta += pendingDelta.height() * pageScale; | |
| 46 | |
| 47 float newContentOffset = m_baselineContentOffset - m_accumulatedScrollDelta; | |
| 48 | |
| 49 setShownRatio(newContentOffset / m_height); | |
| 50 | |
| 51 // Reset baseline when controls are fully visible | |
| 52 if (m_shownRatio == 1) | |
| 53 resetBaseline(); | |
| 54 | |
| 55 // Clamp and use the expected content offset so that we don't return | |
| 56 // spurrious remaining scrolls due to the imprecision of the shownRatio. | |
| 57 newContentOffset = std::min(newContentOffset, m_height); | |
| 58 newContentOffset = std::max(newContentOffset, 0.f); | |
| 59 | |
| 60 // We negate the difference because scrolling down (positive delta) causes | |
| 61 // top controls to hide (negative offset difference). | |
| 62 FloatSize appliedDelta(0, (oldOffset - newContentOffset) / pageScale); | |
| 63 return pendingDelta - appliedDelta; | |
| 64 } | |
| 65 | |
| 66 void TopControls::resetBaseline() { | |
| 67 m_accumulatedScrollDelta = 0; | |
| 68 m_baselineContentOffset = contentOffset(); | |
| 69 } | |
| 70 | |
| 71 float TopControls::layoutHeight() { | |
| 72 return m_shrinkViewport ? m_height : 0; | |
| 73 } | |
| 74 | |
| 75 float TopControls::contentOffset() { | |
| 76 return m_shownRatio * m_height; | |
| 77 } | |
| 78 | |
| 79 void TopControls::setShownRatio(float shownRatio) { | |
| 80 shownRatio = std::min(shownRatio, 1.f); | |
| 81 shownRatio = std::max(shownRatio, 0.f); | |
| 82 | |
| 83 if (m_shownRatio == shownRatio) | |
| 84 return; | |
| 85 | |
| 86 m_shownRatio = shownRatio; | |
| 87 m_frameHost->chromeClient().didUpdateTopControls(); | |
| 88 } | |
| 89 | |
| 90 void TopControls::updateConstraintsAndState(WebTopControlsState constraints, | |
| 91 WebTopControlsState current, | |
| 92 bool animate) { | |
| 93 m_permittedState = constraints; | |
| 94 | |
| 95 DCHECK( | |
| 96 !(constraints == WebTopControlsShown && current == WebTopControlsHidden)); | |
| 97 DCHECK( | |
| 98 !(constraints == WebTopControlsHidden && current == WebTopControlsShown)); | |
| 99 | |
| 100 // If the change should be animated, let the impl thread drive the change. | |
| 101 // Otherwise, immediately set the shown ratio so we don't have to wait for | |
| 102 // a commit from the impl thread. | |
| 103 if (animate) | |
| 104 return; | |
| 105 | |
| 106 if (constraints == WebTopControlsBoth && current == WebTopControlsBoth) | |
| 107 return; | |
| 108 | |
| 109 if (constraints == WebTopControlsHidden || current == WebTopControlsHidden) | |
| 110 setShownRatio(0.f); | |
| 111 else | |
| 112 setShownRatio(1.f); | |
| 113 } | |
| 114 | |
| 115 void TopControls::setHeight(float height, bool shrinkViewport) { | |
| 116 if (m_height == height && m_shrinkViewport == shrinkViewport) | |
| 117 return; | |
| 118 | |
| 119 m_height = height; | |
| 120 m_shrinkViewport = shrinkViewport; | |
| 121 m_frameHost->chromeClient().didUpdateTopControls(); | |
| 122 } | |
| 123 | |
| 124 } // namespace blink | |
| OLD | NEW |