[fenix] For https://github.com/mozilla-mobile/fenix/issues/24648 - Add a Modifier extension method to draw a dashed border

Co-authored-by: Gabriel Luong <gabriel.luong@gmail.com>
pull/600/head
Mugurell 3 years ago committed by mergify[bot]
parent 17350d9339
commit 71d32d1b56

@ -0,0 +1,50 @@
/* 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.compose.ext
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.geometry.CornerRadius
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathEffect
import androidx.compose.ui.graphics.drawscope.Stroke
import androidx.compose.ui.unit.Dp
/**
* Add a dashed border around the current composable.
*
* @param color [Color] to apply to the dashed border.
* @param cornerRadius The corner radius of the rounded rectangle.
* @param dashHeight The thickness of a dash.
* @param dashWidth The length of a dash.
* @param dashGap The size of the gap between the dashes.
*/
fun Modifier.dashedBorder(
color: Color,
cornerRadius: Dp,
dashHeight: Dp,
dashWidth: Dp,
dashGap: Dp = dashWidth
) = this.then(
drawBehind {
val cornerRadiusPx = cornerRadius.toPx()
val borderHeightPx = dashHeight.toPx()
val dashWidthPx = dashWidth.toPx()
val dashGapPx = dashGap.toPx()
val dashedStroke = Stroke(
width = borderHeightPx,
pathEffect = PathEffect.dashPathEffect(
floatArrayOf(dashWidthPx, dashGapPx), 0f
)
)
drawRoundRect(
color = color,
cornerRadius = CornerRadius(cornerRadiusPx),
style = dashedStroke
)
}
)

@ -8,7 +8,6 @@ package org.mozilla.fenix.tabstray.syncedtabs
import android.content.res.Configuration
import androidx.annotation.VisibleForTesting
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
@ -37,9 +36,6 @@ import androidx.compose.runtime.toMutableStateList
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.geometry.CornerRadius
import androidx.compose.ui.graphics.PathEffect
import androidx.compose.ui.graphics.drawscope.Stroke
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.Font
@ -53,6 +49,7 @@ import org.mozilla.fenix.R
import org.mozilla.fenix.compose.Favicon
import org.mozilla.fenix.compose.PrimaryText
import org.mozilla.fenix.compose.SecondaryText
import org.mozilla.fenix.compose.ext.dashedBorder
import org.mozilla.fenix.compose.list.ExpandableListHeader
import org.mozilla.fenix.theme.FirefoxTheme
import org.mozilla.fenix.theme.Theme
@ -75,7 +72,8 @@ fun SyncedTabsList(
onTabClick: (SyncTab) -> Unit,
) {
val listState = rememberLazyListState()
val expandedState = remember(syncedTabs) { syncedTabs.map { EXPANDED_BY_DEFAULT }.toMutableStateList() }
val expandedState =
remember(syncedTabs) { syncedTabs.map { EXPANDED_BY_DEFAULT }.toMutableStateList() }
LazyColumn(
modifier = Modifier.fillMaxSize(),
@ -189,7 +187,11 @@ fun SyncedTabsSectionHeader(
* @param onClick The click handler when this synced tab is clicked.
*/
@Composable
fun SyncedTabsTabItem(tabTitleText: String, url: String, onClick: () -> Unit) {
fun SyncedTabsTabItem(
tabTitleText: String,
url: String,
onClick: () -> Unit
) {
Row(
modifier = Modifier
.clickable(
@ -231,28 +233,21 @@ fun SyncedTabsTabItem(tabTitleText: String, url: String, onClick: () -> Unit) {
* @param errorButton Optional class to set up and handle any clicks in the Error UI.
*/
@Composable
fun SyncedTabsErrorItem(errorText: String, errorButton: SyncedTabsListItem.ErrorButton? = null) {
fun SyncedTabsErrorItem(
errorText: String,
errorButton: SyncedTabsListItem.ErrorButton? = null
) {
Box(
Modifier
.padding(all = 16.dp)
.padding(all = 8.dp)
.height(IntrinsicSize.Min)
) {
val dashColor = FirefoxTheme.colors.borderPrimary
Canvas(Modifier.fillMaxSize()) {
drawRoundRect(
color = dashColor,
style = Stroke(
width = 2.dp.toPx(),
pathEffect = PathEffect.dashPathEffect(floatArrayOf(4.dp.toPx(), 4.dp.toPx()), 0f)
),
cornerRadius = CornerRadius(
x = 8.dp.toPx(),
y = 8.dp.toPx()
),
.dashedBorder(
color = FirefoxTheme.colors.borderPrimary,
cornerRadius = 8.dp,
dashHeight = 2.dp,
dashWidth = 4.dp
)
}
) {
Column(
Modifier
.padding(all = 16.dp)
@ -280,7 +275,10 @@ fun SyncedTabsErrorItem(errorText: String, errorButton: SyncedTabsListItem.Error
* @param onClick The lambda called when the button is clicked.
*/
@Composable
fun SyncedTabsErrorButton(buttonText: String, onClick: () -> Unit) {
fun SyncedTabsErrorButton(
buttonText: String,
onClick: () -> Unit
) {
Button(
onClick = onClick,
modifier = Modifier.clip(RoundedCornerShape(size = 4.dp)),
@ -337,7 +335,10 @@ private fun SyncedTabsListItemsPreview() {
Spacer(modifier = Modifier.height(16.dp))
SyncedTabsTabItem(tabTitleText = "Mozilla", url = "www.mozilla.org") { println("Clicked tab") }
SyncedTabsTabItem(
tabTitleText = "Mozilla",
url = "www.mozilla.org"
) { println("Clicked tab") }
Spacer(modifier = Modifier.height(16.dp))
@ -387,7 +388,8 @@ private fun SyncedTabsListPreview() {
/**
* Helper function to create a List of [SyncedTabsListItem] for previewing.
*/
@VisibleForTesting internal fun getFakeSyncedTabList(): List<SyncedTabsListItem> = listOf(
@VisibleForTesting
internal fun getFakeSyncedTabList(): List<SyncedTabsListItem> = listOf(
SyncedTabsListItem.DeviceSection(
displayName = "Device 1",
tabs = listOf(
@ -403,12 +405,13 @@ private fun SyncedTabsListPreview() {
/**
* Helper function to create a [SyncedTabsListItem.Tab] for previewing.
*/
private fun generateFakeTab(tabName: String, tabUrl: String): SyncedTabsListItem.Tab = SyncedTabsListItem.Tab(
tabName.ifEmpty { tabUrl },
tabUrl,
SyncTab(
history = listOf(TabEntry(tabName, tabUrl, null)),
active = 0,
lastUsed = 0L,
private fun generateFakeTab(tabName: String, tabUrl: String): SyncedTabsListItem.Tab =
SyncedTabsListItem.Tab(
tabName.ifEmpty { tabUrl },
tabUrl,
SyncTab(
history = listOf(TabEntry(tabName, tabUrl, null)),
active = 0,
lastUsed = 0L,
)
)
)

Loading…
Cancel
Save