From c3766967729df19548aedb2cca9bb7884830487f Mon Sep 17 00:00:00 2001 From: Kainalu Hagiwara Date: Fri, 10 Jul 2020 12:40:30 -0700 Subject: [PATCH] Closes #7644: Add long click listener to BrowserMenuItemToolbar items. --- .../menu/item/BrowserMenuItemToolbar.kt | 12 +++++++ .../menu/item/BrowserMenuItemToolbarTest.kt | 33 +++++++++++++++++++ docs/changelog.md | 3 ++ 3 files changed, 48 insertions(+) diff --git a/components/browser/menu/src/main/java/mozilla/components/browser/menu/item/BrowserMenuItemToolbar.kt b/components/browser/menu/src/main/java/mozilla/components/browser/menu/item/BrowserMenuItemToolbar.kt index e0eebb98726..366aba8e8fd 100644 --- a/components/browser/menu/src/main/java/mozilla/components/browser/menu/item/BrowserMenuItemToolbar.kt +++ b/components/browser/menu/src/main/java/mozilla/components/browser/menu/item/BrowserMenuItemToolbar.kt @@ -53,6 +53,11 @@ class BrowserMenuItemToolbar( item.listener() menu.dismiss() } + button.setOnLongClickListener { + item.longClickListener() + menu.dismiss() + true + } layout.addView(button, LinearLayout.LayoutParams(0, MATCH_PARENT, 1f)) } @@ -77,13 +82,16 @@ class BrowserMenuItemToolbar( * @param contentDescription The button's content description, used for accessibility support. * @param iconTintColorResource Optional ID of color resource to tint the icon. * @param isEnabled Lambda to return true/false to indicate if this button should be enabled or disabled. + * @param longClickListener Callback to be invoked when the button is long clicked. * @param listener Callback to be invoked when the button is pressed. */ + @Suppress("LongParameterList") open class Button( @DrawableRes val imageResource: Int, val contentDescription: String, @ColorRes val iconTintColorResource: Int = NO_ID, val isEnabled: () -> Boolean = { true }, + val longClickListener: () -> Unit = {}, val listener: () -> Unit ) { @@ -131,8 +139,10 @@ class BrowserMenuItemToolbar( * @param secondaryImageTintResource Optional ID of secondary color resource to tint the icon. * @param isInPrimaryState Lambda to return true/false to indicate if this button should be primary or secondary. * @param disableInSecondaryState Optional boolean to disable the button when in secondary state. + * @param longClickListener Callback to be invoked when the button is long clicked. * @param listener Callback to be invoked when the button is pressed. */ + @Suppress("LongParameterList") open class TwoStateButton( @DrawableRes val primaryImageResource: Int, val primaryContentDescription: String, @@ -142,12 +152,14 @@ class BrowserMenuItemToolbar( @ColorRes val secondaryImageTintResource: Int = primaryImageTintResource, val isInPrimaryState: () -> Boolean = { true }, val disableInSecondaryState: Boolean = false, + longClickListener: () -> Unit = {}, listener: () -> Unit ) : Button( primaryImageResource, primaryContentDescription, primaryImageTintResource, isInPrimaryState, + longClickListener = longClickListener, listener = listener ) { diff --git a/components/browser/menu/src/test/java/mozilla/components/browser/menu/item/BrowserMenuItemToolbarTest.kt b/components/browser/menu/src/test/java/mozilla/components/browser/menu/item/BrowserMenuItemToolbarTest.kt index 34f50499655..11210315c02 100644 --- a/components/browser/menu/src/test/java/mozilla/components/browser/menu/item/BrowserMenuItemToolbarTest.kt +++ b/components/browser/menu/src/test/java/mozilla/components/browser/menu/item/BrowserMenuItemToolbarTest.kt @@ -297,6 +297,39 @@ class BrowserMenuItemToolbarTest { verify(menu).dismiss() } + @Test + fun `long clicking item view invokes callback and dismisses menu`() { + var callbackInvoked = false + + val button = BrowserMenuItemToolbar.Button( + R.drawable.abc_ic_ab_back_material, + "Test", + longClickListener = { + callbackInvoked = true + } + ) {} + + assertFalse(callbackInvoked) + + val menu = mock(BrowserMenu::class.java) + val layout = LinearLayout(testContext) + + val toolbar = BrowserMenuItemToolbar(listOf(button)) + toolbar.bind(menu, layout) + + assertEquals(1, layout.childCount) + + val view = layout.getChildAt(0) + + assertFalse(callbackInvoked) + verify(menu, never()).dismiss() + + view.performLongClick() + + assertTrue(callbackInvoked) + verify(menu).dismiss() + } + @Test fun `toolbar can be converted to candidate`() { val listener = {} diff --git a/docs/changelog.md b/docs/changelog.md index a359aa03efb..d2c62c9c005 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -27,6 +27,9 @@ permalink: /changelog/ * **browser-state** * Added map of `SessionState.contextId` and their respective `ContainerState` in `BrowserState` to track the state of a container. + +* **browser-menu** + * Added an optional `longClickListener` parameter to `BrowserMenuItemToolbar.Button` and `BrowserMenuItemToolbar.TwoStateButton` to handle long click events. # 49.0.0