From 9ce9240b0a578c08c4d52534daccf29a1bd41d50 Mon Sep 17 00:00:00 2001 From: Ahmed El-Helw Date: Sun, 8 Dec 2024 01:33:20 +0400 Subject: [PATCH] Fix many more toolbar issues After the last PR to fix some RTL toolbar issues, there were other issues that were missed. For example, in landscape RTL, the toolbar was broken. Moreover, it was broken for translations. This patch ensures that the toolbar is well behaved in RTL and LTR in portrait and landscape and in translation mode and normal mode (including on tablet with dual screen and split screen modes). The remaining issues not addressed by this PR are: 1. in landscape, when the toolbar is visible in translation mode and a long press happens on an ayah, the y value is incorrectly lower than the ayah box. 2. in tablet split screen mode, long pressing a translation and then scrolling the translation down does not move the toolbar down. Refs #2993. --- .../labs/androidquran/ui/PagerActivity.kt | 11 +++++ .../quran/page/common/toolbar/AyahToolBar.kt | 45 +++++++++++++++---- 2 files changed, 47 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/com/quran/labs/androidquran/ui/PagerActivity.kt b/app/src/main/java/com/quran/labs/androidquran/ui/PagerActivity.kt index 877e87b063..ae687d7739 100644 --- a/app/src/main/java/com/quran/labs/androidquran/ui/PagerActivity.kt +++ b/app/src/main/java/com/quran/labs/androidquran/ui/PagerActivity.kt @@ -35,6 +35,7 @@ import androidx.core.view.ViewCompat import androidx.core.view.WindowCompat import androidx.core.view.WindowInsetsCompat import androidx.core.view.WindowInsetsControllerCompat +import androidx.core.view.marginEnd import androidx.core.view.updatePadding import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope @@ -483,6 +484,16 @@ class PagerActivity : AppCompatActivity(), AudioBarListener, OnBookmarkTagsUpdat makeText(this@PagerActivity, charSequence!!, Toast.LENGTH_SHORT).show() } + ViewCompat.setOnApplyWindowInsetsListener(ayahToolBar) { view, windowInsets -> + val insets = windowInsets.getInsets( + WindowInsetsCompat.Type.statusBars() or + WindowInsetsCompat.Type.displayCutout() or + WindowInsetsCompat.Type.navigationBars() + ) + ayahToolBar.insets = insets + windowInsets + } + val nonRestoringViewPager = findViewById(R.id.quran_pager) nonRestoringViewPager.setIsDualPagesInLandscape( QuranUtils.isDualPagesInLandscape(this, quranScreenInfo) diff --git a/common/toolbar/src/main/java/com/quran/page/common/toolbar/AyahToolBar.kt b/common/toolbar/src/main/java/com/quran/page/common/toolbar/AyahToolBar.kt index 412b64d9e4..3186a5ec8e 100644 --- a/common/toolbar/src/main/java/com/quran/page/common/toolbar/AyahToolBar.kt +++ b/common/toolbar/src/main/java/com/quran/page/common/toolbar/AyahToolBar.kt @@ -14,6 +14,7 @@ import android.widget.ImageButton import android.widget.LinearLayout import androidx.appcompat.widget.PopupMenu import androidx.core.content.ContextCompat +import androidx.core.graphics.Insets import com.quran.data.model.selection.SelectionIndicator import com.quran.labs.androidquran.common.toolbar.R import com.quran.page.common.toolbar.dao.SelectedAyahPlacementType @@ -48,6 +49,9 @@ class AyahToolBar @JvmOverloads constructor( var longPressLambda: ((CharSequence) -> Unit) = {} var isRecitationEnabled = false var lastMeasuredWidth = 0 + var lastSelectionShouldPadForCutout = false + + var insets: Insets = Insets.NONE @Inject lateinit var ayahToolBarPresenter: AyahToolBarPresenter @@ -115,10 +119,12 @@ class AyahToolBar @JvmOverloads constructor( } // handle first layout of toolbar + val parentWidth = (parent as View).width if (lastMeasuredWidth != totalWidth && lastMeasuredWidth == 0) { // whenever we're RTL, we need to adjust the translationX if (layoutDirection == LAYOUT_DIRECTION_RTL) { - translationX = translationX - totalWidth + val insetToAdd = if (lastSelectionShouldPadForCutout) insets.left + insets.right else 0 + translationX = translationX - (parentWidth - measuredWidth) + insetToAdd } lastMeasuredWidth = totalWidth } @@ -227,17 +233,38 @@ class AyahToolBar @JvmOverloads constructor( // hack to help fix RTL when measuredWidth is not yet set. if this is set, // we adjust the translationX _after_ onLayout lastMeasuredWidth = measuredWidth + val leftInset = if (position is SelectionIndicator.SelectedPointPosition) { + lastSelectionShouldPadForCutout = true + insets.left + insets.right + } else { + lastSelectionShouldPadForCutout = false + 0 + } + val actualX = if (layoutDirection == LAYOUT_DIRECTION_RTL) { - // in RTL, x=0 is on the very right of the screen. translationX is still to the - // right, however (i.e. translationX of 100 is 100 off the screen to the right). - // consequently, we need to subtract the width of the view to get the actual x, - // which is some negative value between -measuredWidth and 0 to properly render - // when RTL. - x - measuredWidth + if (measuredWidth > 0) { + // in RTL, x=0 means the end of the toolbar is touching the very right of the screen, with + // the toolbar itself appearing before the very right of the screen. translationX is still + // to the right, however (i.e. translationX of 100 is 100 off the screen to the right). + // consequently, we need to subtract the width of the view to get the actual x, + // which is some negative value between -measuredWidth and 0 to properly render + // when RTL. + x - (parentView.width - measuredWidth) + leftInset + } else { + // if measuredWidth is not set, we do this step in onLayout instead + x + } } else { - x + x + leftInset } - setPosition(actualX, y) + + val actualY = if (position is SelectionIndicator.SelectedPointPosition) { + y + insets.top + } else { + y + } + + setPosition(actualX, actualY) if (needsLayout) { requestLayout() }