Skip to content

Commit

Permalink
Fix UIKit TextField metrics (#392)
Browse files Browse the repository at this point in the history
Selection handlers
And Context Menu (JetBrains/compose-multiplatform#2682)
  • Loading branch information
dima-avdeev-jb authored and eymar committed Feb 24, 2023
1 parent 9211234 commit 9172a45
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,31 +26,31 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawWithCache
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.text.style.ResolvedTextDirection
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.IntRect
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.times
import androidx.compose.ui.window.Popup
import androidx.compose.ui.window.PopupPositionProvider
import kotlin.math.roundToInt

/**
* Clickable padding of handler
*/
private const val PADDING = 5f
private val PADDING = 5.dp

/**
* Radius of handle circle
*/
private const val RADIUS = 6f
private val RADIUS = 6.dp

/**
* Thickness of handlers vertical line
*/
private const val THICKNESS = 2f
private val THICKNESS = 2.dp

@Composable
internal actual fun SelectionHandle(
Expand All @@ -62,11 +62,15 @@ internal actual fun SelectionHandle(
modifier: Modifier,
content: @Composable (() -> Unit)?
) {
val density = LocalDensity.current
val paddingPx = with(density) { PADDING.toPx() }
val radiusPx = with(density) { RADIUS.toPx() }
val thicknessPx = with(density) { THICKNESS.toPx() }
val isLeft = isLeft(isStartHandle, direction, handlesCrossed)
val y = if (isLeft) {
position.y - PADDING - lineHeight - RADIUS * 2
position.y - paddingPx - lineHeight - radiusPx * 2
} else {
position.y - PADDING
position.y - paddingPx
}

val positionState: State<IntOffset> = rememberUpdatedState(
Expand All @@ -89,23 +93,23 @@ internal actual fun SelectionHandle(
}
) {
Spacer(
modifier.size((PADDING + RADIUS) * 2.dp)
modifier.size((PADDING + RADIUS) * 2)
.drawWithCache {
onDrawWithContent {
drawContent()
// vertical line
drawRect(
color = handleColor,
topLeft = Offset(
x = PADDING + RADIUS - THICKNESS / 2,
y = if (isLeft) PADDING + RADIUS else PADDING - lineHeight
x = paddingPx + radiusPx - thicknessPx / 2,
y = if (isLeft) paddingPx + radiusPx else paddingPx - lineHeight
),
size = Size(THICKNESS, lineHeight + RADIUS)
size = Size(thicknessPx, lineHeight + radiusPx)
)
// handle circle
drawCircle(
color = handleColor,
radius = RADIUS,
radius = radiusPx,
center = center
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,15 +165,25 @@ internal actual class ComposeWindow : UIViewController {
onPasteRequested: (() -> Unit)?,
onCutRequested: (() -> Unit)?,
onSelectAllRequested: (() -> Unit)?
) = skikoUIView.showTextMenu(
targetRect = rect.toSkiaRect(),
textActions = object: TextActions {
override val copy: (() -> Unit)? = onCopyRequested
override val cut: (() -> Unit)? = onCutRequested
override val paste: (() -> Unit)? = onPasteRequested
override val selectAll: (() -> Unit)? = onSelectAllRequested
) {
val skiaRect = with(density) {
org.jetbrains.skia.Rect.makeLTRB(
l = rect.left / density,
t = rect.top / density,
r = rect.right / density,
b = rect.bottom / density,
)
}
)
skikoUIView.showTextMenu(
targetRect = skiaRect,
textActions = object : TextActions {
override val copy: (() -> Unit)? = onCopyRequested
override val cut: (() -> Unit)? = onCutRequested
override val paste: (() -> Unit)? = onPasteRequested
override val selectAll: (() -> Unit)? = onSelectAllRequested
}
)
}

/**
* TODO on UIKit native behaviour is hide text menu, when touch outside
Expand Down

0 comments on commit 9172a45

Please sign in to comment.