79151568

Date: 2024-11-02 20:57:54
Score: 1
Natty:
Report link

The post by @Thracian made me investigate their code, and then combined it with the code for CutCornerShape and RoundedCornerShape.

Here's the SemiRoundCutCornerShape

fun SemiRoundCutCornerShape(size: Dp, roundedLeft: Boolean = true) = SemiRoundCutCornerShape(size, size, roundedLeft)

fun SemiRoundCutCornerShape(cutSize: Dp, roundSize: Dp, roundedLeft: Boolean = true) = SemiRoundCutCornerShape(
    topStart = CornerSize(roundSize),
    topEnd = CornerSize(cutSize),
    bottomEnd = CornerSize(roundSize),
    bottomStart = CornerSize(cutSize),
    roundedLeft = roundedLeft
)

class SemiRoundCutCornerShape(
    topStart: CornerSize,
    topEnd: CornerSize,
    bottomEnd: CornerSize,
    bottomStart: CornerSize,
    private val roundedLeft: Boolean = true
) : CornerBasedShape(
    topStart = topStart,
    topEnd = topEnd,
    bottomEnd = bottomEnd,
    bottomStart = bottomStart,
) {

    override fun createOutline(
        size: Size,
        topStart: Float,
        topEnd: Float,
        bottomEnd: Float,
        bottomStart: Float,
        layoutDirection: LayoutDirection
    ): Outline {
        val roundOutline: Outline = Outline.Rounded(
            when (layoutDirection == LayoutDirection.Ltr && roundedLeft) {
                true -> RoundRect(
                    rect = size.toRect(),
                    topLeft = CornerRadius(if (layoutDirection == LayoutDirection.Ltr) topStart else topEnd),
                    bottomRight = CornerRadius(if (layoutDirection == LayoutDirection.Ltr) bottomEnd else bottomStart),
                )
                false -> RoundRect(
                    rect = size.toRect(),
                    topRight = CornerRadius(if (layoutDirection == LayoutDirection.Ltr) topEnd else topStart),
                    bottomLeft = CornerRadius(if (layoutDirection == LayoutDirection.Ltr) bottomStart else bottomEnd)
                )
            }
        )
        val cutOutline: Outline = Outline.Generic(
            when (layoutDirection == LayoutDirection.Ltr && roundedLeft) {
                true -> Path().apply {
                    var cornerSize = 0F
                    moveTo(0f, cornerSize)
                    lineTo(cornerSize, 0f)
                    cornerSize = topEnd
                    lineTo(size.width - cornerSize, 0f)
                    lineTo(size.width, cornerSize)
                    cornerSize = 0F
                    lineTo(size.width, size.height - cornerSize)
                    lineTo(size.width - cornerSize, size.height)
                    cornerSize = bottomStart
                    lineTo(cornerSize, size.height)
                    lineTo(0f, size.height - cornerSize)
                    close()
                }
                false -> Path().apply {
                    var cornerSize = topEnd
                    moveTo(0f, cornerSize)
                    lineTo(cornerSize, 0f)
                    cornerSize = 0F
                    lineTo(size.width - cornerSize, 0f)
                    lineTo(size.width, cornerSize)
                    cornerSize = bottomStart
                    lineTo(size.width, size.height - cornerSize)
                    lineTo(size.width - cornerSize, size.height)
                    cornerSize = 0F
                    lineTo(cornerSize, size.height)
                    lineTo(0f, size.height - cornerSize)
                    close()
                }
            }

        )

        return Outline.Generic(Path.combine(
            operation = PathOperation.Intersect,
            path1 = Path().apply { addOutline(cutOutline) },
            path2 = Path().apply { addOutline(roundOutline) }
        ))
    }

    override fun copy(
        topStart: CornerSize,
        topEnd: CornerSize,
        bottomEnd: CornerSize,
        bottomStart: CornerSize
    ): CornerBasedShape = SemiRoundCutCornerShape(
        topStart = topStart,
        topEnd = topEnd,
        bottomEnd = bottomEnd,
        bottomStart = bottomStart
    )

    override fun toString(): String {
        return "SemiRoundCutShape(topStart = $topStart, topEnd = $topEnd, bottomEnd = " +
                "$bottomEnd, bottomStart = $bottomStart)"
    }
}

Here used to create

SemiRoundCutCornerShape(8.dp)
SemiRoundCutCornerShape(24.dp, roundedLeft = false)
SemiRoundCutCornerShape(16.dp)
SemiRoundCutCornerShape(
  topStart = CornerSize(60.dp),
  topEnd = CornerSize(8.dp),
  bottomEnd = CornerSize(16.dp),
  bottomStart = CornerSize(20.dp)
)

Shapes illustrating code example

Reasons:
  • Probably link only (1):
  • Long answer (-1):
  • Has code block (-0.5):
  • User mentioned (1): @Thracian
  • Self-answer (0.5):
Posted by: Yokich