You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
135 lines
5.1 KiB
Kotlin
135 lines
5.1 KiB
Kotlin
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
package org.mozilla.fenix.components
|
|
|
|
import android.view.View
|
|
import android.view.ViewGroup.MarginLayoutParams
|
|
import androidx.annotation.UiThread
|
|
import androidx.annotation.VisibleForTesting
|
|
import androidx.core.view.isVisible
|
|
import mozilla.components.browser.state.selector.findCustomTabOrSelectedTab
|
|
import mozilla.components.browser.state.store.BrowserStore
|
|
import mozilla.components.browser.toolbar.BrowserToolbar
|
|
import mozilla.components.concept.engine.EngineView
|
|
import mozilla.components.feature.findinpage.FindInPageFeature
|
|
import mozilla.components.feature.findinpage.view.FindInPageBar
|
|
import mozilla.components.support.base.feature.LifecycleAwareFeature
|
|
import mozilla.components.support.base.feature.UserInteractionHandler
|
|
import org.mozilla.fenix.components.FindInPageIntegration.ToolbarInfo
|
|
|
|
/**
|
|
* BrowserFragment delegate to handle all layout updates needed to show or hide the find in page bar.
|
|
*
|
|
* @property store The [BrowserStore] used to look up the current selected tab.
|
|
* @property sessionId ID of the [store] session in which the query will be performed.
|
|
* @property view The [FindInPageBar] view to display.
|
|
* @property engineView the browser in which the queries will be made and which needs to be better positioned
|
|
* to suit the find in page bar.
|
|
* @property toolbarInfo [ToolbarInfo] used to configure the [BrowserToolbar] while the find in page bar is shown.
|
|
*/
|
|
class FindInPageIntegration(
|
|
private val store: BrowserStore,
|
|
private val sessionId: String? = null,
|
|
private val view: FindInPageBar,
|
|
private val engineView: EngineView,
|
|
private val toolbarInfo: ToolbarInfo,
|
|
) : LifecycleAwareFeature, UserInteractionHandler {
|
|
private val feature by lazy { FindInPageFeature(store, view, engineView, ::onClose) }
|
|
|
|
override fun start() {
|
|
feature.start()
|
|
}
|
|
|
|
override fun stop() {
|
|
feature.stop()
|
|
}
|
|
|
|
override fun onBackPressed(): Boolean {
|
|
return feature.onBackPressed()
|
|
}
|
|
|
|
private fun onClose() {
|
|
view.visibility = View.GONE
|
|
restorePreviousLayout()
|
|
}
|
|
|
|
/**
|
|
* Start the find in page functionality.
|
|
*/
|
|
@UiThread
|
|
fun launch() {
|
|
onLaunch(view, feature)
|
|
}
|
|
|
|
private fun onLaunch(view: View, feature: LifecycleAwareFeature) {
|
|
store.state.findCustomTabOrSelectedTab(sessionId)?.let { tab ->
|
|
prepareLayoutForFindBar()
|
|
|
|
view.visibility = View.VISIBLE
|
|
(feature as FindInPageFeature).bind(tab)
|
|
view.layoutParams.height = toolbarInfo.toolbar.height
|
|
}
|
|
}
|
|
|
|
@VisibleForTesting
|
|
internal fun restorePreviousLayout() {
|
|
toolbarInfo.toolbar.isVisible = true
|
|
|
|
val engineViewParent = getEngineViewParent()
|
|
val engineViewParentParams = getEngineViewsParentLayoutParams()
|
|
if (toolbarInfo.isToolbarPlacedAtTop) {
|
|
if (toolbarInfo.isToolbarDynamic) {
|
|
engineViewParent.translationY = toolbarInfo.toolbar.height.toFloat()
|
|
engineViewParentParams.bottomMargin = 0
|
|
} else {
|
|
engineViewParent.translationY = 0f
|
|
}
|
|
} else {
|
|
if (toolbarInfo.isToolbarDynamic) {
|
|
engineViewParentParams.bottomMargin = 0
|
|
}
|
|
}
|
|
}
|
|
|
|
@VisibleForTesting
|
|
internal fun prepareLayoutForFindBar() {
|
|
toolbarInfo.toolbar.isVisible = false
|
|
|
|
val engineViewParent = getEngineViewParent()
|
|
val engineViewParentParams = getEngineViewsParentLayoutParams()
|
|
if (toolbarInfo.isToolbarPlacedAtTop) {
|
|
if (toolbarInfo.isToolbarDynamic) {
|
|
// With a dynamic toolbar the EngineView extends to the entire (top and bottom) of the screen.
|
|
// And now with the toolbar expanded it is translated down immediately below the toolbar.
|
|
engineViewParent.translationY = 0f
|
|
engineViewParentParams.bottomMargin = toolbarInfo.toolbar.height
|
|
} else {
|
|
// With a fixed toolbar the EngineView is anchored below the toolbar with 0 Y translation.
|
|
engineViewParent.translationY = -toolbarInfo.toolbar.height.toFloat()
|
|
}
|
|
} else {
|
|
// With a bottom toolbar the EngineView is already anchored to the top of the screen.
|
|
// Need just to ensure space for the find in page bar under the engineView.
|
|
engineViewParentParams.bottomMargin = toolbarInfo.toolbar.height
|
|
}
|
|
}
|
|
|
|
@VisibleForTesting
|
|
internal fun getEngineViewParent() = engineView.asView().parent as View
|
|
|
|
@VisibleForTesting
|
|
internal fun getEngineViewsParentLayoutParams() = getEngineViewParent().layoutParams as MarginLayoutParams
|
|
|
|
/**
|
|
* Holder of all details needed about the Toolbar.
|
|
* Used to modify the layout of BrowserToolbar while the find in page bar is shown.
|
|
*/
|
|
data class ToolbarInfo(
|
|
val toolbar: BrowserToolbar,
|
|
val isToolbarDynamic: Boolean,
|
|
val isToolbarPlacedAtTop: Boolean,
|
|
)
|
|
}
|